【问题标题】:Typescript $inject $timeout into a directive ... works in controller, not in linkTypescript $inject $timeout into a directive ...在控制器中工作,而不是在链接中
【发布时间】: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 仍然是新事物,还有很多最佳实践尚未定义。我团队项目的一部分是找到其中的一些。
  • 我们一直在研究这个总体结构,所以除非有令人信服的理由,否则请不要建议我过多地改变所有结构。

【问题讨论】:

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


    【解决方案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);
        }
    }
    

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

    【讨论】:

    • 谢谢你的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多