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.
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);
It's generally better to use a
function
+module
instead of aclass
when writing an Angular filter. You can structure the code like this:You could also place both
FriendlyDateFilter
declarations inside anothermodule
if you're trying to avoid adding too much to the global scope.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:
and it registers the filter with the following code:
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]
You can find my project here, and a sample of filter here
First, you need to use
angular.d.ts
definition file.Then, you simply do the following :
$inject
property is available inFunction
thanks to these lines inangular.d.ts
:See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/angularjs/angular.d.ts#L12
You can use classes to inject dependencies, just use the [] in the module and use method injection as below: