Angular 与 Typescript 和指令中未定义的注入服务
Posted
技术标签:
【中文标题】Angular 与 Typescript 和指令中未定义的注入服务【英文标题】:Angular with Typescript and undefined injected service in directive 【发布时间】:2015-10-28 02:17:07 【问题描述】:我正在尝试从指令访问服务,但无论我做什么,它们似乎都未定义。 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() (或做与功能无关的其他事情),所有(或某些)服务会突然变得未定义。这是非常奇怪的行为,非常令人沮丧。
我的应用程序中有多个指令,指令中有多个指令。似乎有时所有服务都没有正确加载或其他什么,我也尝试更改应用程序的设置。
我试图将此行为复制到这个 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。
【问题讨论】:
您的服务注册为myService
还是大写M MyService
?
在 app.ts 中注册为.service("myService", MyService)
,所以没有大写m。
【参考方案1】:
将您的工厂方法更改为以下。您需要在指令的原型中注入服务。
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);
【讨论】:
仍然说未定义 :( 我将 var 指令更改为:var directive = (myService: Foo.MyService) => console.log(myService); console.log(Foo.MyService); return new MyDirective(myService);
并且两个 console.logs 都未定义
看起来我们生成的javascripts除了这个之外几乎是相同的: var self = this;这是如何在打字稿中完成的?虽然我不确定这是否能解决我在工厂中的问题(myService 未定义,当你的应该是 Object 时)
我已经粘贴了打字稿。两个变化 (1) 在链接方法中使用 lambda 表达式。它将为您创建闭包。 (2) 指令类的静态工厂方法中的directive.$inject = ['myService']
好的,现在服务不再是未定义的,但是当尝试将 this.myService.getBar() 分配给 scope.foo 时,出现错误:错误:[$compile:nonassign] Expression 'undefined ' 与指令 'myDirective' 一起使用是不可赋值的! docs.angularjs.org/error/$compile/…
这是你的标记的问题。你能分享你的 html 吗?你是如何使用你的指令的?以上是关于Angular 与 Typescript 和指令中未定义的注入服务的主要内容,如果未能解决你的问题,请参考以下文章
Angular 指令使用 Typescript 接收对象作为属性
typescript 用于在输入中显示/隐藏密码的Angular7指令