【问题标题】:Inject dependency to the angularjs directive using typescript使用 typescript 注入对 angularjs 指令的依赖
【发布时间】:2015-06-16 21:03:42
【问题描述】:

假设我有一个简单的角度指令,如下所示:

app.directive('setFocus', ['$timeout', function($timeout) {
return {
    restrict: 'AC',
    link: function(_scope, _element) {
        $timeout(function() {
            _element[0].focus();
        }, 0);
    }
};
}]);

如何使用 Typescript 编写此代码并在链接函数中获取 $timeout ?我的示例如下所示:

/// <reference path="../../reference.ts"/>

class SetFocus{
    constructor() {
        var directive: ng.IDirective = {};
        directive.restrict = 'EA';
        directive.scope = { };        
        directive.link= function ($scope, $element, $attrs) {
        // How can I access $timeout here?

        }
        return directive;
    }
}

directives.directive('setFocus', [SetFocus]);

这可能是一个愚蠢的例子,但这是我想要开始工作的原则,即在角度链接函数中使用注入的依赖项。

【问题讨论】:

    标签: angularjs angularjs-directive typescript


    【解决方案1】:

    试试这个方法:

    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());
    

    这可能是您现在拥有它的方式的问题。因为指令工厂没有更新,所以它的构造函数将以this 作为全局对象执行。这样你最终也不会拥有一个庞大的构造函数,并且可以以适当的类 ey 方式编写它。

    如果您注入了许多依赖项而不是在工厂中重复参数,您也可以这样做:

      var directive: ng.IDirectiveFactory =
                (...args) => new (SetFocus.bind.apply(SetFocus, [null].concat(args)));
    

    【讨论】:

      【解决方案2】:

      为了避免所有工厂样板(以及构造函数数组),我最近写了一个小库(目前作为测试项目),它使指令的定义非常简单(这里省略了控制器和模板):

      @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);
          }
      
      }
      

      它使用像 @Directive 这样的装饰器和自定义版本的 TypeScript 编译器,使接口元数据在运行时可用(因此 ng.IQService 可以转换为 '$q' 并注入到构造函数数组中)。 不再有app.directive(...) 样板:一切都在装饰器中完成:) 可以看一下示例应用代码here

      【讨论】:

        猜你喜欢
        • 2014-12-04
        • 2015-08-28
        • 2013-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-21
        • 2014-10-14
        • 2013-04-10
        相关资源
        最近更新 更多