Can somebody provide me with an example of how I can create an Angular Filter in TypeScript that uses dependency injection. At the bottom is what I currently have, which is working fine, but what I want to do is in is the function I want to have access to $filter, so that I can change the line return date.ToString() into $filter'date'. That way I use the built in date filter to show a nice friendly short date.
有人可以向我提供一个示例,说明如何在TypeScript中使用依赖注入创建角度过滤器。在底部是我目前拥有的,它工作正常,但我想要做的是我想要访问$ filter的函数,以便我可以将行返回date.ToString()更改为$ filter '日期'。这样我就可以使用内置的日期过滤器来显示友好的短暂日期。
class FriendlyDateFilter {
public static Factory() {
return function (input): string {
if (angular.isDate(input)) {
var date: Date = input;
var today = new Date();
var days = Math.abs(getDaysBetweenDates(today, date));
if (days < 7) {
var dayInWeek = date.getDay();
switch (dayInWeek) {
case 0:
return "Sunday";
break;
case 1:
return "Monday";
break;
case 2:
return "Tuesday";
break;
case 3:
return "Wednesday";
break;
case 4:
return "Thursday";
break;
case 5:
return "Friday";
break;
case 6:
return "Saturday";
break;
}
} else {
return date.toString();
}
} else {
return input;
}
}
function getDaysBetweenDates(d0, d1) {
var msPerDay = 8.64e7;
// Copy dates so don't mess them up
var x0: any = new Date(d0);
var x1: any = new Date(d1);
// Set to noon - avoid DST errors
x0.setHours(12, 0, 0);
x1.setHours(12, 0, 0);
// Round to remove daylight saving errors
return Math.round((x1 - x0) / msPerDay);
}
}
}
}
angular.module("ReadingLog").filter("FriendlyDateFilter", FriendlyDateFilter.Factory);
4 个解决方案
#1
3
It's generally better to use a function
+module
instead of a class
when writing an Angular filter. You can structure the code like this:
在编写Angular过滤器时,通常最好使用函数+模块而不是类。您可以像这样构造代码:
function FriendlyDateFilter($filter) {
return function (s: string): string {
/* Your logic here */
}
/* Helper logic here */
}
module FriendlyDateFilter {
export var $inject = ['$filter'];
}
angular.module("ReadingLog").filter("FriendlyDateFilter", FriendlyDateFilter);
You could also place both FriendlyDateFilter
declarations inside another module
if you're trying to avoid adding too much to the global scope.
如果您试图避免向全局范围添加太多,也可以将FriendlyDateFilter声明放在另一个模块中。
#2
3
First, you need to use angular.d.ts
definition file.
首先,您需要使用angular.d.ts定义文件。
Then, you simply do the following :
然后,您只需执行以下操作:
MyFilter.$inject = ["$log"];
function MyFilter ($log: ng.ILogService): Function {
return function(msg: string) {
$log.log("I'm injected!");
return msg;
};
}
angular.module("testModule").filter("MyFilter", MyFilter);
$inject
property is available in Function
thanks to these lines in angular.d.ts
:
由于angular.d.ts中的这些行,$ inject属性在函数中可用:
// Support for painless dependency injection
interface Function {
$inject?: string[];
}
See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/angularjs/angular.d.ts#L12
#3
0
I had the same problem while writing my own DI system for AngularJs 1.3 & Typescript. To solve this I wrote a decorator that accepts a class that implements the following interface:
在为AngularJs 1.3和Typescript编写自己的DI系统时遇到了同样的问题。为了解决这个问题,我写了一个装饰器,它接受一个实现以下接口的类:
interface IFilter {
filter(value?: any, ...args): any;
}
and it registers the filter with the following code:
并使用以下代码注册过滤器:
var filterFactory = (...args) => {
var filterObject = new target(...args);
if (typeof filterObject.filter === 'function') {
return filterObject.filter.bind(filterObject);
}
console.warn('Invalid filter: filter() method not found for:', filterName)
return function() { }; //dummy filter, so it won't break everything
};
var constructorArray: Array<any> = injector.resolveParamNames(target);
app.filter(filterName, constructorArray.concat(filterFactory));
My library uses a custom version of the TypeScript compiler, which is able to emit interface metadata that is used by injector.resolveParamNames
to build the classic constructor array like this one: ['$q', '$timeout', FilterFactory]
我的库使用TypeScript编译器的自定义版本,它能够发出inject.resolveParamNames使用的接口元数据来构建经典的构造函数数组,如下所示:['$ q','$ timeout',FilterFactory]
You can find my project here, and a sample of filter here
你可以在这里找到我的项目,以及这里的过滤器样本
#4
0
You can use classes to inject dependencies, just use the [] in the module and use method injection as below:
您可以使用类来注入依赖项,只需使用模块中的[]并使用方法注入,如下所示:
module Filters {
export class MyFilter {
public static Factory(injectableService: InjectableService) {
return function (input:any) {
// use injectableService to affect your input in desired way
return input;
}
}
}
angular.module('app')
.filter('myFilter', ['injectableService', MyFilter.Factory]);
#1
3
It's generally better to use a function
+module
instead of a class
when writing an Angular filter. You can structure the code like this:
在编写Angular过滤器时,通常最好使用函数+模块而不是类。您可以像这样构造代码:
function FriendlyDateFilter($filter) {
return function (s: string): string {
/* Your logic here */
}
/* Helper logic here */
}
module FriendlyDateFilter {
export var $inject = ['$filter'];
}
angular.module("ReadingLog").filter("FriendlyDateFilter", FriendlyDateFilter);
You could also place both FriendlyDateFilter
declarations inside another module
if you're trying to avoid adding too much to the global scope.
如果您试图避免向全局范围添加太多,也可以将FriendlyDateFilter声明放在另一个模块中。
#2
3
First, you need to use angular.d.ts
definition file.
首先,您需要使用angular.d.ts定义文件。
Then, you simply do the following :
然后,您只需执行以下操作:
MyFilter.$inject = ["$log"];
function MyFilter ($log: ng.ILogService): Function {
return function(msg: string) {
$log.log("I'm injected!");
return msg;
};
}
angular.module("testModule").filter("MyFilter", MyFilter);
$inject
property is available in Function
thanks to these lines in angular.d.ts
:
由于angular.d.ts中的这些行,$ inject属性在函数中可用:
// Support for painless dependency injection
interface Function {
$inject?: string[];
}
See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/angularjs/angular.d.ts#L12
#3
0
I had the same problem while writing my own DI system for AngularJs 1.3 & Typescript. To solve this I wrote a decorator that accepts a class that implements the following interface:
在为AngularJs 1.3和Typescript编写自己的DI系统时遇到了同样的问题。为了解决这个问题,我写了一个装饰器,它接受一个实现以下接口的类:
interface IFilter {
filter(value?: any, ...args): any;
}
and it registers the filter with the following code:
并使用以下代码注册过滤器:
var filterFactory = (...args) => {
var filterObject = new target(...args);
if (typeof filterObject.filter === 'function') {
return filterObject.filter.bind(filterObject);
}
console.warn('Invalid filter: filter() method not found for:', filterName)
return function() { }; //dummy filter, so it won't break everything
};
var constructorArray: Array<any> = injector.resolveParamNames(target);
app.filter(filterName, constructorArray.concat(filterFactory));
My library uses a custom version of the TypeScript compiler, which is able to emit interface metadata that is used by injector.resolveParamNames
to build the classic constructor array like this one: ['$q', '$timeout', FilterFactory]
我的库使用TypeScript编译器的自定义版本,它能够发出inject.resolveParamNames使用的接口元数据来构建经典的构造函数数组,如下所示:['$ q','$ timeout',FilterFactory]
You can find my project here, and a sample of filter here
你可以在这里找到我的项目,以及这里的过滤器样本
#4
0
You can use classes to inject dependencies, just use the [] in the module and use method injection as below:
您可以使用类来注入依赖项,只需使用模块中的[]并使用方法注入,如下所示:
module Filters {
export class MyFilter {
public static Factory(injectableService: InjectableService) {
return function (input:any) {
// use injectableService to affect your input in desired way
return input;
}
}
}
angular.module('app')
.filter('myFilter', ['injectableService', MyFilter.Factory]);