javascript - 当用作 Angular 4 AoT 的 useValue 提供程序时,窗口未定义

标签 javascript angular typescript angular2-aot angular-compiler-cli

当 Angular 4.0.2 应用程序提前编译时,提供者定义为 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 {}

它编译正常,但导致 window 被注入(inject)时 undefined

constructor(@Inject(windowToken) window) {
   window.navigator...
}

引导时抛出错误:

TypeError: Cannot read property 'navigator' of undefined

仔细观察自动生成的 app.module.ngfactory.js,它似乎确实是 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时,一切正常:

export function windowFactory() {
  return window;
}
export const windowProvider = { provide: windowToken, useFactory: windowFactory };

在这里使用 window 作为 useValue 提供者到底有什么问题?这是一个已知的陷阱吗?此限制是否适用于所有全局变量或所有 useValue 提供程序?

最佳答案

我遇到了类似的问题,但它与 SignalrWindow 有关。尽管概念和错误是相同的。

然后我在这里找到这篇文章(https://blog.sstorie.com/integrating-angular-2-and-signalr-part-2-of-2/),文章底部有一些评论帮助我解决了问题。

基本上,它归结为在提供程序中使用工厂方法而不是 useValue。我不确定为什么会出现问题,但我知道这种方法可以解决 aot 问题。

修复步骤:

创建一个导出的函数

export function windowFactory(): any {
    return window;
}

然后在核心模块中,在 vendor 的 @NgModule 中,您可以这样做:

...
providers: [
    { provide: SignalrWindow, useFactory: windowFactory }
  ]
...

基本上,您可以根据自己的喜好重命名这些方法(因此,在您的示例中它将是:)

export const windowProvider = { provide: windowToken, useFactory: windowFactory };

关于javascript - 当用作 Angular 4 AoT 的 useValue 提供程序时,窗口未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43445947/

相关文章:

javascript - AngularJS 的 ng-table 重新加载不起作用

javascript - 如何使用 .show() 从顶部而不是从左侧创建隐藏的 div 缓动?

Javascript 函数在控制台中有效,但在代码中无效

javascript - 使用中间对齐的 div 防止动画摆动

html - 从列表中检索到的所选项目的新列表

angular - Karma 使用内置管道的自定义管道测试 Angular X (5) 组件

javascript - 使用 typescript 作为自定义数据类型在 Angular 中返回 Promise

javascript - WebStorm TypeScript 检查错误 - 未实时显示?

javascript - 如何获取 Angular 2中的第一个父scrollTop元素?

typescript :箭头功能的通用功能类型/接口(interface)