我正在使用一个外部库,一旦浏览器加载了库的javascript文件,该库便会将其自身附加到全局窗口对象(window ['lib'])。每当尝试加载组件时,我都试图使用此库调用代码,但是每次尝试访问该对象时,它都是未定义的(由于未加载库)。我已经尝试了所有可以想到的生命周期挂钩,但是似乎没有什么可以等待DOM完全准备就绪。例如,我想做这样的事情:
ngOnInit() {
window['lib'].doStuff(); // <-- window['lib'] is undefined
}
如果我将其包装为超时,则它将变为可用。但是,这看起来像是代码异味,并且不想这样处理:
ngOnInit() {
setTimeout(function() {
window['lib'].doStuff(); // <-- this works
});
}
解决这个问题的最佳/建议/“最成角度的方式”是什么?谢谢!
答案 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
标签的日子已经一去不复返了。