Angular with Typescript和undefined注入服务的指令

时间:2015-08-05 10:43:14

标签: angularjs angularjs-directive typescript

我正在尝试从指令访问服务,但无论我做什么,它们似乎都是未定义的。 MyDirective.factory()在初始化指令时表示未定义。在构造函数中也未定义(毫不奇怪)。

我试图像这些说明一样做,但无济于事:
http://blog.aaronholmes.net/writing-angularjs-directives-as-typescript-classes/
http://sirarsalih.com/2014/08/04/proper-dependency-injection-in-your-angularjs-typescript-apps/
Define AngularJS directive using TypeScript and $inject mechanism

这是app.ts:

angular.module("fooTest", [])
    .service("myService", Foo.MyService)
    .directive("myDirective", Foo.MyDirective.factory());

MyDirective.ts:

module Foo {
'use strict';

export class MyDirective implements ng.IDirective {

    private myService: any;

    //static $inject = ['myService'];

    constructor(service: MyService) {
        this.myService = service;
    }

    restrict = "E";
    replace = true;
    template = "<div ng-click='fooClick()'>foo: {{foo}}</div>";
    scope = {
        foo: "="
    };

    link = (scope, element, attrs) => {
        scope.fooClick = function () {
            this.myService.foo();
            scope.foo = this.myService.getBar();
        }
    };

    static factory() {
        console.log("factory");
        var directive = (myService: Foo.MyService) => new MyDirective(myService);
        directive['$inject'] = ['myService'];
        return directive;
    }
}
}

和MyService.ts:

module Foo {
    'use strict';

    export class MyService {

    foo() {
        console.log("bar");
    }

    getBar() {
        return "bar";
    }
}
} 

<小时/> 编辑

上面的Foo示例在下面的答案的帮助下工作得很好但是当我使用类似的方式在我的实际应用程序中注入服务时,它的功能非常奇怪。一切都可能正常工作一段时间,但如果我在某处添加一个console.log()(或做一些与功能无关的事情),所有(或某些)服务都会突然变得不确定。这是非常奇怪的行为,非常令人沮丧。

我的app和指令中有几个指令。似乎有时所有服务都没有正确加载或者其他东西,我也尝试更改应用程序的设置。

我试图将此行为复制到此Foo示例中,似乎我通过在第一个中使用另一个指令来实现它。然后服务随机定义。

现在 MyDirective.ts 模板:

template = "<div><div ng-click='fooClick()'>foo: {{foo}}</div><br/><another-directive test='bar'></another-directive></div>";

AnotherDirective.ts

module Foo {
'use strict';

export class AnotherDirective implements ng.IDirective {

    private myService: any;

    constructor(public service: MyService) {
        this.myService = service;
    }

    restrict = "E";
    replace = true;
    template = "<div ng-click='barClick()'>bar: {{test}}</div>";
    scope = {
        test: "="
    };

    link = (scope, element, attrs) => {
        scope.barClick = () => {
            //console.log(this.myService);
            scope.test = this.myService.getFoo();
        }
    };

    static factory(): ng.IDirectiveFactory {
        var directive = (myService: Foo.MyService) => new AnotherDirective(myService);
        directive.$inject = ['myService'];
        return directive;
    }

}
}  

如果我在任一指令中取消注释/注释console.logs,那么服务将是未定义的。或者如果我做其他与功能无关的事情。怎么了?

如果我在链接功能中使用console.log(this),它会显示“AnotherDirective {myService:Object ...”。但是当它失败时它会显示“Scope {$ id:3,$$ childTail:null,$$ childHead:...”

在我在app.ts中包含的_references.ts中,订单是MyService,AnotherDirective,MyDirective,app。

1 个答案:

答案 0 :(得分:6)

将您的工厂方法更改为以下。您需要在指令的原型中注入服务。

  static factory() {
        console.log("factory");
        var directive = (myService: Foo.MyService) => new MyDirective(myService);
        directive.$inject = ['myService'];
        return directive;
    }

结帐http://plnkr.co/edit/DnU3N2BBZXCpdmmVZNbA?p=preview

打字稿

module Foo {
'use strict';

export class MyDirective implements ng.IDirective {

    private myService: any;

    //static $inject = ['myService'];

    constructor(service: MyService) {
        this.myService = service;
    }

    restrict = "E";
    replace = true;
    template = "<div ng-click='fooClick()'>foo: {{foo}}</div>";
    scope = {
        foo: "="
    };

    link = (scope, element, attrs) => {
        scope.fooClick =  () => {
            this.myService.foo();
            scope.foo = this.myService.getBar();
        }
    };

    static factory() {
        console.log("factory");
        var directive = (myService: Foo.MyService) => new MyDirective(myService);
        directive.$inject = ['myService'];
        return directive;
    }
}
}

module Foo {
    'use strict';

    export class MyService {

    foo() {
        console.log("bar");
    }

    getBar() {
        return "bar";
    }
}
}

angular.module("fooTest", []).
    directive("myDirective", Foo.MyDirective.factory()).
    service("myService", Foo.MyService);