簡體   English   中英

使用typescript注入angularjs指令的依賴項

[英]Inject dependency to the angularjs directive using typescript

假設我有一個簡單的角度指令,如下所示:

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

這可能是一個愚蠢的例子,但它是我想要工作的原則,它在角度鏈接函數中使用注入的依賴項。

試試這種方式:

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

為了避免所有的工廠樣板(以及構造函數數組),我最近編寫了一個小型庫(目前作為測試項目),它使指令的定義非常簡單(這里省略了控制器和模板):

@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(...)樣板:一切都在裝飾器中完成:)你可以在這里看一下示例應用程序代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM