当用作Angular 4 AoT的useValue提供程序时,窗口是未定义的 [英] window is undefined when used as useValue provider with Angular 4 AoT
问题描述
当提前编译Angular 4.0.2应用程序时,提供程序定义为 useValue
When Angular 4.0.2 application is compiled ahead-of-time, and the provider is defined as useValue
import { OpaqueToken, Provider } from '@angular/core';
export const windowToken = new OpaqueToken('window');
export const windowProvider = { provide: windowToken, useValue: window };
并使用像
@NgModule({ providers: [windowProvider], ... })
export class AppModule {}
它编译好了,但是当注入为
窗口为 undefined
> it compiles ok but results in window
being undefined
when injected as
constructor(@Inject(windowToken) window) {
window.navigator...
}
引导时抛出错误:
TypeError:无法读取未定义的属性'navigator'
TypeError: Cannot read property 'navigator' of undefined
仔细查看自动生成的app.module.ngfactory .js似乎确实未定义
:
On a closer look at auto-generated app.module.ngfactory.js it appears that it is indeed undefined
:
...
import * as import39 from './window';
var AppModuleInjector = (function (_super) {
...
AppModuleInjector.prototype.createInternal = function () {
...
this._windowToken_26 = undefined;
this._SomeService_27 = new import16.SomeService(this._windowToken_26);
}
AppModuleInjector.prototype.getInternal = function (token, notFoundResult) {
...
if ((token === import39.windowToken)) {
return this._windowToken_26;
}
...
当同一服务用作 useFactory
时,一切正常:
When the same service is used as useFactory
, everything is ok:
export function windowFactory() {
return window;
}
export const windowProvider = { provide: windowToken, useFactory: windowFactory };
使用窗口出现了什么问题
as useValue
provider here?这是一个已知的陷阱吗?这个限制是否适用于所有的glob als或者所有 useValue
提供者?
What exactly is wrong with using window
as useValue
provider here? Is it a known pitfall? Does this limitation apply to all globals or all useValue
providers?
推荐答案
我遇到了类似的问题但是有一个SignalrWindow。概念和错误虽然相同。
I was having a similar problem but it was with a SignalrWindow. The concept and the error though was identical.
然后我在这里找到了这篇文章( https://blog.sstorie.com/integrating-angular-2-and-signalr-part-2-of-2/ ),文章底部有一些评论帮助我解决了这个问题。
I then found this article here (https://blog.sstorie.com/integrating-angular-2-and-signalr-part-2-of-2/), and there were some comments at the bottom of the article that helped me solve the problem.
基本上,它已经完成了使用工厂方法提供者中的useValue。我不确定为什么这是一个问题,但我知道这种方法解决了问题。
Basically, it boils done to using a factory method instead of a useValue in the providers. I'm not sure why it's a problem, but I do know that this approach solves the aot problem.
要修复的步骤:
创建导出的函数
export function windowFactory(): any {
return window;
}
然后在核心模块中,在 @NgModule
在提供商中你可以这样做:
Then in the core module, in @NgModule
in the providers you can do this:
...
providers: [
{ provide: SignalrWindow, useFactory: windowFactory }
]
...
基本上,您可以根据需要重命名方法(因此,在您的示例中它将是:)
Basically, you can rename the methods however you like (so, in your example it would be:)
export const windowProvider = { provide: windowToken, useFactory: windowFactory };
这篇关于当用作Angular 4 AoT的useValue提供程序时,窗口是未定义的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!