Angular 2+ Window属性未定义

时间:2018-06-27 23:54:43

标签: javascript angular angular-components angular-lifecycle-hooks

我正在使用一个外部库,一旦浏览器加载了库的javascript文件,该库便会将其自身附加到全局窗口对象(window ['lib'])。每当尝试加载组件时,我都试图使用此库调用代码,但是每次尝试访问该对象时,它都是未定义的(由于未加载库)。我已经尝试了所有可以想到的生命周期挂钩,但是似乎没有什么可以等待DOM完全准备就绪。例如,我想做这样的事情:

ngOnInit() {
    window['lib'].doStuff(); // <-- window['lib'] is undefined
}

如果我将其包装为超时,则它将变为可用。但是,这看起来像是代码异味,并且不想这样处理:

ngOnInit() {
    setTimeout(function() {
        window['lib'].doStuff(); // <-- this works
    });
}

解决这个问题的最佳/建议/“最成角度的方式”是什么?谢谢!

1 个答案:

答案 0 :(得分:2)

角度生命周期挂钩:ngOnInit()

  

在Angular首先显示指令后初始化指令/组件   数据绑定属性并设置指令/组件的输入   属性。

     

在第一个ngOnChanges()之后调用一次。

这是Angular的常见问题。像这样的较旧方法在窗口对象上使用全局变量将使Angular加载应用程序以及TypeScript(在开发过程中)的方式烦恼。之所以必须window['lib']而不是window.lib是因为TypeScript对window.lib的类型一无所知,因此window['lib']是强制其工作的一种方式

另一部分是,取决于所使用的编译类型(AOT与JIT),您正在加载的库可能尚未准备就绪(还取决于您如何加载)该脚本/模块进入应用程序)。正如商业自杀提到的那样,您可以尝试其他Angular Lifecycle Hooks,但更有可能的是,您最终将选择setTimeout。实际上,您甚至不需要定义超时时间,也可以传递0ms(如您在代码中所做的那样)。 Angular只希望您等到DOM完成渲染后才调用该函数。

我个人等不及将所有类似于jQuery的库都转换为正确的ES6模块。在script底部扔一个body标签的日子已经一去不复返了。