Атрибут Angular 2+ Window не определен - PullRequest
0 голосов
/ 28 июня 2018

Я использую внешнюю библиотеку, которая присоединяется к глобальному объекту окна (window ['lib']), как только файл javascript библиотеки загружается браузером. Я пытаюсь вызвать код с использованием этой библиотеки всякий раз, когда компонент загружается, однако каждый раз, когда я пытаюсь получить доступ к объекту, он не определен (из-за того, что библиотека не была загружена). Я перепробовал все возможные варианты жизненного цикла, но, похоже, ничто не может дождаться полной готовности DOM. Например, я хочу сделать что-то вроде этого:

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

Если я заверну его в тайм-аут, он станет доступным. Однако это похоже на запах кода и не хочет подходить к нему следующим образом:

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

Каков наилучший / рекомендуемый / «наиболее угловой» способ решения этой проблемы? Спасибо!

1 Ответ

0 голосов
/ 28 июня 2018

Угловой крюк жизненного цикла: ngOnInit()

Инициализировать директиву / компонент после того, как Angular впервые отобразит привязанные к данным свойства и устанавливает ввод директивы / компонента свойства.

Вызывается один раз, после первого ngOnChanges ().

Это общая проблема с Angular. Более старые методологии, подобные этой, использующие глобальную переменную в объекте окна, будут раздражать то, как Angular загружает приложение, а также TypeScript (во время разработки). Причина, по которой вам нужно сделать window['lib'], а не window.lib, заключается в том, что TypeScript ничего не знает о типах window.lib, поэтому window['lib'] - это способ заставить его работать.

Другая часть заключается в том, что в зависимости от того, какой тип компиляции вы используете ( AOT против JIT), загружаемая вами библиотека может быть или не быть готова (также зависит от того, как вы повторная загрузка этого скрипта / модуля в приложение). Как уже упоминалось в разделе «Коммерческое самоубийство», вы можете попробовать другие Angular Lifecycle Hooks , но, скорее всего, вы в конечном итоге остановитесь на setTimeout. На самом деле вам даже не нужно определять период ожидания, или вы можете передать 0 мс (как вы сделали в своем коде). Angular просто хочет, чтобы вы откладывали вызов этой функции до тех пор, пока DOM не закончит рендеринг.

Лично я не могу дождаться, пока все jQuery-подобные библиотеки будут преобразованы в соответствующие модули ES6. Дни простого добавления метки script внизу body давно прошли.

...