为什么在这个 angular2 示例中我仍然需要 @inject?
Why do I still need @inject in this angular2 example?
这可能是一个特殊情况(注入浏览器本机 window 对象),但是我还是有点困惑为什么我仍然需要 @Inject() 参数装饰器 class 已经有一个 @Injectable() 装饰器。
举个简单的例子:
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 })
]);
概述: 我们有一个令牌 class 表示一个对象,该对象可以在一个组件或另一个服务中多次存在(因此没有单例)。令牌 class 取决于全局 window 对象(例如,用于 base64 编码)。
为了使其可测试,我们在 bootstrap 期间为全局 window object 定义了一个应用范围的提供程序,而不是直接在令牌服务中使用它。
主要组件需要动态创建令牌,因此我们创建并注入一个简单的工厂服务 TokenFactory,它还需要 window 提供程序(将其传递给构建期间的代币 class)。
问题:在浏览器中执行时失败并出现错误
Can't resolve all parameters for TokenFactory: (?).
但可以通过向工厂构造函数添加 @Inject(Window) 装饰器来修复 window 参数。
现在,我有点困惑,因为大多数 guides/tutorials 解释说在使用 Injectable 装饰器装饰 class 时,打字稿中不需要 inject 装饰器,所以为什么不使用 @Inject() decorator?
示例会失败
Config: emitDecoratorMetadata 和 experimentalDecorators 设置已启用,我正在使用 tsc 1.8.10 和 angular2 rc.3.
PS: 我也愿意接受一般设计改进。
(例如,在生产场景中,我可能只会导出 Token 接口,而不是整个 class)
我不清楚问题到底是什么,但是
如果没有 @Inject(...)
,type string
对于可注入的构造函数参数没有任何意义
@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()
应该从此 class 中删除。
关于错误消息:似乎 Window
未正确导入或者它不是类型而是 OpaqueToken
或 string
.
如果依赖注入应该使用与参数类型不同的键,则需要 @Inject()
。在您的情况下,它看起来 Window
不是一种类型 (class),因此在这样使用时不起作用。
这可能是一个特殊情况(注入浏览器本机 window 对象),但是我还是有点困惑为什么我仍然需要 @Inject() 参数装饰器 class 已经有一个 @Injectable() 装饰器。
举个简单的例子:
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 })
]);
概述: 我们有一个令牌 class 表示一个对象,该对象可以在一个组件或另一个服务中多次存在(因此没有单例)。令牌 class 取决于全局 window 对象(例如,用于 base64 编码)。 为了使其可测试,我们在 bootstrap 期间为全局 window object 定义了一个应用范围的提供程序,而不是直接在令牌服务中使用它。
主要组件需要动态创建令牌,因此我们创建并注入一个简单的工厂服务 TokenFactory,它还需要 window 提供程序(将其传递给构建期间的代币 class)。
问题:在浏览器中执行时失败并出现错误
Can't resolve all parameters for TokenFactory: (?).
但可以通过向工厂构造函数添加 @Inject(Window) 装饰器来修复 window 参数。
现在,我有点困惑,因为大多数 guides/tutorials 解释说在使用 Injectable 装饰器装饰 class 时,打字稿中不需要 inject 装饰器,所以为什么不使用 @Inject() decorator?
示例会失败Config: emitDecoratorMetadata 和 experimentalDecorators 设置已启用,我正在使用 tsc 1.8.10 和 angular2 rc.3.
PS: 我也愿意接受一般设计改进。
(例如,在生产场景中,我可能只会导出 Token 接口,而不是整个 class)
我不清楚问题到底是什么,但是
如果没有@Inject(...)
,type string
对于可注入的构造函数参数没有任何意义
@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()
应该从此 class 中删除。
关于错误消息:似乎 Window
未正确导入或者它不是类型而是 OpaqueToken
或 string
.
@Inject()
。在您的情况下,它看起来 Window
不是一种类型 (class),因此在这样使用时不起作用。