Typescript$inject$timeout到指令中..在控制器中工作,而不是在链接中

Typescript $inject $timeout into a directive ... works in controller, not in link

本文关键字:链接 工作 控制器 timeout 指令 Typescript inject      更新时间:2023-09-26

堆栈:Typescript 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);
    }
}

在指令中连接它。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仍然是新的,还有很多最佳实践远未定义。我的团队项目的一部分就是找到其中的一些
  • 我们已经在这个总体结构上工作了一段时间,所以除非有令人信服的原因,否则请不要建议我过多地改变一切的结构

链接函数不是直接从指令实例执行的,因此您不会将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) {
    }
}

或者,您可以使用函数.bind(即link = MyLink;)绑定上下文,并使用this.$timeout访问$timeout

如果interseted,您可以考虑通过使用指令的实验装饰器来创建一些语法糖,或者您可以尝试探索类似的东西。然而(只是我的观点)使用类进行指令配置似乎有些过头了,您还可以使用带有静态注入的函数。

链接函数第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);
    }
}

我知道这并不优雅,但我很难找到更好的解决方案,你觉得呢?