4

I'm using an external library that attaches itself to the global window object (window['lib']) once the library's javascript file is loaded by the browser. I'm trying to invoke code using this library whenever a component is loaded, however everytime I try to access the object it is undefined (due to the library not having been loaded). I have tried every lifecycle hook I can think of, however nothing appears to wait for the DOM to be fully ready. For example, I want to do something like this:

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

If I wrap it in a timeout, then it becomes available. However, this looks like code smell and do not want to approach it this way:

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

What is the best / suggested / "most angular way" to approach this problem? Thanks!

4

1 回答 1

2

Angular 生命周期钩子:ngOnInit()

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

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

这是 Angular 的常见问题。像这种在窗口对象上使用全局变量的旧方法会惹恼 Angular 加载应用程序的方式以及 TypeScript(在开发期间)。你必须做window['lib']而不是做的原因是因为 TypeScript 对sowindow.lib的类型一无所知,这是一种强制它工作的方法。window.libwindow['lib']

另一部分是,根据您使用的编译类型(AOT与 JIT),您正在加载的库可能尚未准备好或尚未准备好(还取决于您如何将该脚本/模块加载到应用程序中)。正如 Commercial Suicide 所提到的,您可以尝试其他一些Angular 生命周期挂钩,但很有可能您最终会选择setTimeout. 实际上,您甚至不需要定义超时时间,或者您可以通过 0ms(正如您在代码中所做的那样)。Angular 只是希望您推迟调用该函数,直到 DOM 完成渲染。

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

于 2018-06-28T00:12:53.930 回答