这可能是一个特殊情况(注入浏览器本机窗口对象),但是当我的类已经有@Injectable()时,我仍然对为什么我仍然需要@Inject()参数装饰器感到困惑。装饰器。
采用这个简化的例子:
import { provide, bootstrap, Injectable, Inject } from '@angular/core';
@Injectable()
export class Token {
private token: string;
public constructor(token: string, window: Window) {
this.token = window.atob(token);
};
public getToken(): string {
return this.token;
}
}
@Injectable()
export class TokenFactory {
private window: Window;
public constructor(window: Window) {
this.window = window;
}
public createToken(token: string): Token {
return new Token(token, this.window);
}
}
@Component({
template: `
<p *ngFor="let token of tokens">
Encoded: {{token.getToken()}}
</p>
`,
providers: [ TokenFactory ]
})
class MainComponent {
public tokens: Token[];
public constructor(factory: TokenFactory) {
this.tokens = [
factory.create('token-1'),
factory.create('token-2')
];
};
}
bootstrap(
MainComponent, [
provide(Window, { useValue: window })
]);
概述:我们有一个令牌类,它代表一个可能在组件或其他服务中多次存在的对象(因此没有单例)。令牌类取决于全局窗口对象(例如,用于base64编码)。 为了使这个可测试,我们在引导期间为全局window object定义了应用程序范围的提供程序,而不是直接在令牌服务中使用它。
主要组件需要动态创建令牌,因此我们创建并注入一个简单的工厂服务 TokenFactory ,它还需要窗口提供程序(在构造期间将其传递给令牌类)。
问题:在浏览器中执行错误
时失败Can't resolve all parameters for TokenFactory: (?).
但可以通过将@Inject(Window)装饰器添加到工厂构造函数 window 参数来修复。
现在,我有点困惑,因为大多数指南/教程解释说,在使用Injectable装饰器装饰类时,typescript中不需要注入装饰器,所以为什么示例在不使用@Inject的情况下失败()装饰者?
配置: emitDecoratorMetadata 和 experimentalDecorators 设置已启用,我正在使用 tsc 1.8.10 和 angular2 rc.3 。
PS: 我也开放进行一般设计改进。
(例如,在生产场景中,我可能只会导出令牌界面而不是整个类)
答案 0 :(得分:5)
我不清楚这个问题到底是什么,但是
如果没有string
,注入的构造函数参数的类型@Inject(...)
没有任何意义
@Injectable()
export class Token {
private token: string;
public constructor(token: string, window: Window) { // <<== invalid
this.token = window.atob(token);
};
public getToken(): string {
return this.token;
}
}
但是因为你正在使用它
new Token(token, this.window);
似乎应该从此课程中删除@Injectable()
。
关于错误消息:看起来Window
未正确导入,或者类型不是OpaqueToken
或string
。
@Inject()
。在您的情况下,Window
看起来不是类型(类),因此在使用时不起作用。