Typescript $将$ timeout注入指令...在控制器中工作,而不是在链接中工作

时间:2016-03-24 22:31:42

标签: javascript angularjs angularjs-directive typescript angular-directive

堆栈: 打字稿1.7 + Angular 1.49

要点:

我有一个指令。我希望$inject有角度的$timeout服务。它在指令的控制器功能中工作正常,但在链接功能中没有。我错过了什么?

问题:

  • 我做错了什么?
  • $inject $timeout依赖项的更好方法吗?
  • 为什么$timeout服务在指令的控制器中工作,而不是链接?

MyDirective.ts:

module app.directives {

    export class MyDirective {
        priority = 0;
        restrict = 'E';
        templateUrl = 'template.html';
        scope = {
            'items': '='
        };
        controller = MyController;
        link = MyLink;

        static $inject = ['$timeout'];

        constructor(private  $timeout:ng.ITimeoutService) {
        }
    }

    function MyController($scope:ng.IScope, $timeout:ng.ITimeoutService) {
        console.log("controller", $timeout); // function timeout(fn,delay,invokeApply){ the guts here }
        $timeout(function () {
            console.log("This works fine");
        },3000);
    }

    function MyLink(scope:ng.IScope, element:ng.IAugmentedJQuery, attr:ng.IAttributes, $timeout:ng.ITimeoutService) {
        console.log("link to", $timeout); // MyController {}
        $timeout(function () {
            console.log("This throws the error, TypeError: $timeout is not a function");
        },3000);
    }
}

在directives.ts中连接:

module app.directives {
    angular.module('app').directive('MyDirective',['$timeout',($timeout:ng.ITimeoutService) => new MyDirective($timeout) ]);
}

app.ts

module app {
    angular.module('app', []);
}

什么没有用?

  • 在MyLink中使用this.$timeout,参数中包含或不包含$timeout
  • 我发现了一些文章和示例,我试图确保我遵循我的应用程序的逻辑,但似乎无法得到它。

最后的笔记

  • Typescript-Angular仍然是新的,有很多最佳实践远未被定义。我团队的一部分项目是找到其中的一部分。
  • 我们一直在研究这种一般结构,所以除非有令人信服的理由,否则请不要过多地改变所有结构的建议。

2 个答案:

答案 0 :(得分:6)

链接函数不是直接从指令实例执行的,因此您不会将this作为Directive的配置实例(通过new运算符实例化)。此外,您不能向链接函数注入任何内容(即指令构造函数用于),与控制器构造函数不同,链接函数的参数由指令执行逻辑自动传入。您可以使用箭头运算符来解决此问题。

示例:

 export class MyDirective {
    priority = 0;
    restrict = 'E';
    templateUrl = 'template.html';
    scope = {
        'items': '='
    };
    controller = MyController;

    link:ng.IDirectiveLinkFn = (scope:ng.IScope, element:ng.IAugmentedJQuery, attr:ng.IAttributes) => {

      //Here
      this.$timeout(function () {

      },3000);
    };

    constructor(private  $timeout:ng.ITimeoutService) {
    }
}

或者您可以使用function.bind绑定上下文。即link = MyLink;并使用$timeout访问this.$timeout

如果你可以通过使用实验装饰器来指导创建一些语法糖,或者你可以尝试探索一些like this。但是(只是我的意见)使用类指令配置似乎是一种矫枉过正,你可能只是使用静态注入的函数。

答案 1 :(得分:1)

链接功能第4个参数是他自己的控制器实例。

如果你想这样做,你应该做一些事情:

module app.directives {

    export class MyDirective {
        link = MyLink;

        static $inject = ['$timeout'];

        constructor(public $timeout:ng.ITimeoutService) {
        }
    }

    function MyLink(scope:ng.IScope, element:ng.IAugmentedJQuery, attr:ng.IAttributes, ctrl:any) {
        ctrl.$timeout(function () {
            console.log("This throws the error, TypeError: $timeout is not a function");
        },3000);
    }
}

我知道这不优雅,但我很难找到更好的解决方案,您怎么看?