当用作Angular 4 AoT的useValue提供程序时,窗口是未定义的 [英] window is undefined when used as useValue provider with Angular 4 AoT

查看:282
本文介绍了当用作Angular 4 AoT的useValue提供程序时,窗口是未定义的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当提前编译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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆