Typescript $inject $timeout into a directive ...在控制器中工作,而不是在链接中
Posted
技术标签:
【中文标题】Typescript $inject $timeout into a directive ...在控制器中工作,而不是在链接中【英文标题】:Typescript $inject $timeout into a directive ... works in controller, not in link 【发布时间】:2016-07-12 16:30:08 【问题描述】:堆栈: 打字稿 1.7 + Angular 1.49
总结:
我有一个指令。我想$inject
angular 的$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 仍然是新事物,还有很多最佳实践尚未定义。我团队项目的一部分是找到其中的一些。 我们一直在研究这个总体结构,所以除非有令人信服的理由,否则请不要建议我过多地改变所有结构。【问题讨论】:
【参考方案1】:链接函数不会直接从指令实例执行,因此您不会将 this
作为指令的配置实例(您通过 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;
并使用this.$timeout
访问$timeout
。
如果有兴趣,您可以看看通过使用实验性装饰器来创建一些语法糖,或者您可以尝试探索like this。但是(只是我的观点)使用一个类进行指令配置似乎有点过头了,你还不如只使用一个带有静态注入的函数。
【讨论】:
好一个,比我的好。【参考方案2】:链接函数第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);
我知道这并不优雅,但我很难找到更好的解决方案,你觉得呢?
【讨论】:
谢谢你的回答!以上是关于Typescript $inject $timeout into a directive ...在控制器中工作,而不是在链接中的主要内容,如果未能解决你的问题,请参考以下文章
[Vue + TS] Use Dependency Injection in Vue Using @Inject and @Provide Decorators with TypeScript(代码片
Typescript $inject $timeout into a directive ...在控制器中工作,而不是在链接中
处理使用typescript在类实例化中反转@inject()参数
typescript DI - Bootstrap和Inject装饰器上的提供者注册
Karma + Jasmine 下 angular.mock.inject 的 TypeScript AngularJS 控制器测试问题