AngularJS Filter with TypeScript and injection

后端 未结 4 1062
没有蜡笔的小新
没有蜡笔的小新 2021-01-12 15:26

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

相关标签:
4条回答
  • 2021-01-12 15:36

    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]);
    
    0 讨论(0)
  • 2021-01-12 15:39

    First, you need to use angular.d.ts definition file.

    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:

    // Support for painless dependency injection
    interface Function {
      $inject?: string[];
    }
    

    See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/angularjs/angular.d.ts#L12

    0 讨论(0)
  • 2021-01-12 15:58

    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:

    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.

    0 讨论(0)
  • 2021-01-12 15:58

    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:

    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]

    You can find my project here, and a sample of filter here

    0 讨论(0)
提交回复
热议问题