lam*_*ade 9 javascript dependency-injection typescript angular angular8
我有两个使用这些版本的Angular项目:
在版本9中,我使用它来提供和注入window对象:
@NgModule({
providers: [
{
provide: Window,
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject(Window) private window: Window)
}
Run Code Online (Sandbox Code Playgroud)
哪个工作正常。
将这种方法用于版本8会在编译期间引发警告和错误:
警告:无法解析TestComponent的所有参数……
我通过使用单引号解决了它,如下所示:
@NgModule({
providers: [
{
provide: 'Window',
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject('Window') private window: Window)
}
Run Code Online (Sandbox Code Playgroud)
这两个版本有什么区别?
导致此问题的Angular 8和9有什么区别?
考虑ValueProvider接口:
export declare interface ValueProvider extends ValueSansProvider {
/**
* An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`.
*/
provide: any;
/**
* When true, injector returns an array of instances. This is useful to allow multiple
* providers spread across many files to provide configuration information to a common token.
*/
multi?: boolean;
}
Run Code Online (Sandbox Code Playgroud)
该provide属性为 类型any。这意味着任何对象(包括Window构造函数)都可以进入其中。对象实际上并不重要,只有引用才重要,以确定应该使用哪个提供程序在构造函数中注入参数。
使用本机构Window造函数作为注入令牌不应被视为一种好的做法。它在编译时失败,因为它Window在运行时存在于浏览器环境中,它也作为 TypeScript 存在,declare但 Angular 8 编译器无法进行静态代码分析来关联Window提供者和Window构造函数中的参数,因为赋值Window已经完成通过浏览器,而不是代码。不知道为什么它在 Angular 9 中有效,但......
您应该创建自己的表示依赖项提供程序的注入令牌。此注入令牌应该是:
'Window')InjectionToken。例如export const window = new InjectionToken<Window>('window');此外,Angular 代码应该与平台无关(应该可以在浏览器和 Node.js 服务器上执行),所以最好使用返回window或undefined/的工厂null,然后在组件中处理undefined/null情况。
为了使您的应用程序能够与服务器端渲染一起使用,我建议您不仅使用窗口通过令牌,而且还以SSR友好的方式创建此令牌,而无需完全引用window。Angular具有DOCUMENT用于访问的内置令牌document。这是我想出的让项目window通过令牌使用的内容:
import {DOCUMENT} from '@angular/common';
import {inject, InjectionToken} from '@angular/core';
export const WINDOW = new InjectionToken<Window>(
'An abstraction over global window object',
{
factory: () => {
const {defaultView} = inject(DOCUMENT);
if (!defaultView) {
throw new Error('Window is not available');
}
return defaultView;
},
},
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
186 次 |
| 最近记录: |