Как запустить функцию jquery в Angular 2 после каждой загрузки компонента
Я пробовал все крючки жизненного цикла, но не могу достичь необходимого результата.
В результате мне понадобится функция, которая инициализирует многие плагины jquery, используемые для разных элементов на одной странице, после загрузки каждого из этих элементов (компонентов).
Итак, давайте скажем, что у вас есть эта структура.
Главная страница ползунок Виджеты Ротаторы продукта..etc
Каждый из этих элементов имеет свой собственный компонент и все являются дочерними элементами родительского компонента главной страницы.
И мне здесь нужно знать, когда загружаются все дочерние компоненты и родительский компонент, поэтому я запускаю одну функцию jquery для инициализации каждого плагина на странице.
Ответы
Ответ 1
Вы хотите использовать крючок жизненного цикла ngAfterViewInit, импортируя AfterViewInit (https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#afterview). Вы можете использовать его, как показано ниже:
Установка:
tsd install jquery --save
или
typings install dt~jquery --global --save
Использование:
import { Component, AfterViewInit } from '@angular/core';
declare var $:JQueryStatic;
ngAfterViewInit() {
this.doJqueryLoad();
this.doClassicLoad();
$(this.el.nativeElement)
.chosen()
.on('change', (e, args) => {
this.selectedValue = args.selected;
});
}
doClassicLoad() {
// A $( document ).ready() block.
$( document ).ready(function() {
console.log( "Unnecessary..." );
});
}
// You don't need to use document.ready...
doJqueryLoad() {
console.log("Can use jquery without doing document.ready")
var testDivCount = $('#testDiv').length;
console.log("TestDivCount: ", testDivCount);
}
Вот пример плунжера для примера:
http://plnkr.co/edit/KweZYO9hk9Dz8pqDK77F?p=info
Ответ 2
Наиболее эффективным способом, который я нашел, является использование setTimeout со временем 0 внутри конструктора страницы/компонента. Это позволяет jQuery запускаться в следующем цикле выполнения после завершения Angular загрузки всех дочерних компонентов.
export class HomePage {
constructor() {
setTimeout(() => {
// run jQuery stuff here
}, 0);
}
}
Использование setTimeout внутри метода ngOnInit также сработало для меня.
export class HomePage {
ngOnInit() {
setTimeout(() => {
// run jQuery stuff here
}, 0);
}
}
Ответ 3
как насчет
bootstrap(...).then(x => {
...
})
В противном случае я бы предположил, что ngAfterViewInit()
вашего корневого компонента является крючком жизненного цикла, который соответствует вашему требованию, но вы заявили, что уже все тестировали...
Обновление
bootstrap()
или ngAfterViewInit()
в корневом компоненте может использоваться только для начальной загрузки. Для более поздних добавленных компонентов можно использовать ngAfterViewInit()
добавленных компонентов.
Ответ 4
У меня была такая же проблема. Я нашел 2 решения, даже они не самые лучшие:
1 - Внесите afterViewChecked, чтобы проверить, запущен ли плагин jquery, а затем использовать переменную для управления ее инициализацией. Это трудный путь, потому что afterViewChecked вызывается много раз.
2 - Я изменил некоторые элементы, которые нужно скрыть, используя скрытое свойство вместо ngIf. С помощью hidden я мог бы инициализировать все jquery-плагины с помощью afterViewInit и заставить их работать, даже мои объекты скрыты.
setTimeout не работает при использовании ngIf. Он запускается до повторного отображения содержимого.
Ответ 5
Одним из возможных решений будет подписка на zone.onStable
или zone.onMicrotaskEmpty
ngAfterViewInit() {
this.zone.onStable.first().subscribe(() => {
debugger;
});
}
или
ngOnInit() {
this.service.getData().subscribe(() => {
this.data = data;
this.zone.onMicrotaskEmpty.first().subscribe((data) => {
$(someElem).plugin();
});
});
}
См. также