Inject dependency to the angularjs directive using typescript

前端 未结 2 1879
谎友^
谎友^ 2020-12-31 22:27

Lets say I have a simple angular directive that looks like this:

app.directive(\'setFocus\', [\'$timeout\', function($timeout) {
return {
    restrict: \'AC\         


        
相关标签:
2条回答
  • 2020-12-31 22:27

    To avoid all the factory boilerplate (and the constructor array at all), I recently wrote a small library (currently as a test project), that make the definition of directives very simple (controller and template omitted here):

    @Directive('userRank')
    export class UserRankDirective implements ng.IDirective {
    
        controller = UserRankDirectiveController;
        restrict = 'A';
        template = template;
        //controllerAs: 'ctrl', set as default
        replace = true;
        scope = {
            user: '=userRank'
        }
    
        constructor($q: ng.IQService) {
            console.log('Q service in UserRankDirective:', $q);
        }
    
    }
    

    It uses decorators like @Directive and a customized version of the TypeScript compiler that make interfaces metadata available at runtime (so ng.IQService can be translated to '$q' and injected in the constructor array). No more app.directive(...) boilerplate: everything is done in decorators :) You can give a look at the sample application code here

    0 讨论(0)
  • 2020-12-31 22:35

    Try this way:

    class SetFocus implements ng.IDirective {
        //Directive settings
        restrict :string = 'EA';
        scope : any= {};
        //Take timeout argument in the constructor
        constructor(private $timeout: ng.ITimeoutService) {
        }
    
        link: ng.IDirectiveLinkFn = ($scope: ng.IScope, $element: ng.IAugmentedJQuery, $attrs: ng.IAttributes) => {
              //refer to the timeout
              this.$timeout(function() {
                $element[0].focus();
             }, 0);
        }
        //Expose a static func so that it can be used to register directive.
        static factory(): ng.IDirectiveFactory {
           //Create factory function which when invoked with dependencies by
           //angular will return newed up instance passing the timeout argument
            var directive: ng.IDirectiveFactory = 
                  ($timeout:ng.ITimeoutService) => new SetFocus($timeout);
            //directive's injection list
            directive.$inject = ["$timeout"];
            return directive;
        }
    }
    
    directives.directive('setFocus', SetFocus.factory());
    

    It could be a problem with the way you have it right now. Because directive factory is not newed up so its constructor will execute with this as global object. This way you don't end up having a huge constructor as well and can write it in proper class ey manner.

    If you have many dependencies injected instead of repeating the arguments in the factory you could as well do:

      var directive: ng.IDirectiveFactory =
                (...args) => new (SetFocus.bind.apply(SetFocus, [null].concat(args)));
    
    0 讨论(0)
提交回复
热议问题