Dependency injection 为什么在这个angular2示例中仍然需要@inject?
这可能是一种特殊情况(注入浏览器本机窗口对象),但我还是有点困惑,为什么我的类已经有了@Injectable()decorator,而我仍然需要@injection()参数decorator 以这个简化的例子为例:Dependency injection 为什么在这个angular2示例中仍然需要@inject?,dependency-injection,angular,factory-pattern,Dependency Injection,Angular,Factory Pattern,这可能是一种特殊情况(注入浏览器本机窗口对象),但我还是有点困惑,为什么我的类已经有了@Injectable()decorator,而我仍然需要@injection()参数decorator 以这个简化的例子为例: 从'@angular/core'导入{provide,bootstrap,Injectable,injection}; @可注射() 导出类令牌{ 私有令牌:字符串; 公共构造函数(标记:字符串,窗口:窗口){ this.token=window.atob(token); }; pu
从'@angular/core'导入{provide,bootstrap,Injectable,injection};
@可注射()
导出类令牌{
私有令牌:字符串;
公共构造函数(标记:字符串,窗口:窗口){
this.token=window.atob(token);
};
public getToken():字符串{
返回此.token;
}
}
@可注射()
出口级代币厂{
私人窗口:窗口;
公共构造函数(窗口:窗口){
this.window=窗口;
}
公共createToken(令牌:字符串):令牌{
返回新令牌(令牌,此.window);
}
}
@组成部分({
模板:`
编码:{{token.getToken()}}
`,
提供者:[令牌工厂]
})
类主组件{
公共代币:代币[];
公共构造函数(工厂:令牌工厂){
此参数为。令牌=[
factory.create('token-1'),
创建('token-2')
];
};
}
引导(
主要组成部分[
提供(窗口,{useValue:Window})
]);
概述:我们有一个令牌类,它表示一个对象,该对象可以在一个组件或另一个服务中多次存在(因此没有单例)。令牌类取决于全局窗口对象(例如,对于base64编码)。
为了使这一点可测试,我们在引导期间为全局服务定义了一个应用程序范围的提供者,而不是在令牌服务中直接使用它
主组件需要动态创建令牌,因此我们创建并注入一个简单的工厂服务令牌工厂,该工厂还需要窗口提供程序(在构建期间将令牌类传递给它)
问题:在浏览器中执行此操作时失败,并出现错误
Can't resolve all parameters for TokenFactory: (?).
但可以通过向Factorys构造函数窗口参数添加@Inject(Window)装饰器来修复
现在,我有点困惑了,因为大多数指南/教程解释说,在用可注入装饰器装饰类时,typescript中不需要注入装饰器,那么为什么这个示例没有使用@inject()装饰器就失败了呢
Config:emitDecoratorMetadata和experimentalDecorators设置已启用,我正在使用tsc 1.8.10和angular2 rc.3
PS:我也对总体设计改进持开放态度
(例如,在生产场景中,我可能只导出令牌接口,而不是整个类)我不清楚问题的实质是什么,但是 如果没有
@Inject(…)
似乎应该从这个类中删除@Injectable()
关于错误消息:看起来
窗口
未正确导入,或者它不是类型,而是OpaqueToken
或字符串
如果依赖项注入应使用与参数类型不同的键,则需要使用
@Inject()
。在您的情况下,它看起来像是Window
不是一个类型(类),因此在这样使用时不起作用。您能详细介绍一下Window类的定义位置和导入方式吗?谢谢它是作为窗口公开的全局浏览器(lover case)。它在引导过程中被注入底部。嗯…,在这种情况下,提供者名称是否必须是字符串或更好的OpaqueToken,因为typescript/angular可能会混淆窗口名称属性?我忘了提到,这是一个运行时(浏览器)错误,而不是编译时(tsc)…很好,你是对的,我应该删除Token类的可注入项,因为令牌参数不打算被注入,实际上更多的是一个输入参数。您关于窗口的评论让人耳目一新,因为窗口对象来自浏览器,它可能没有经过修饰(没有元数据),因此需要在Factorys窗口参数上使用InjectDocorator;听起来不错。
@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);