私はすべてのライフサイクルフックを試しましたが、必要な結果を達成することができません。私が必要とする結果は、これらの要素(コンポーネント)が1つ1つ読み込まれた後に、1つのページ上のさまざまな要素に使用される多くのjqueryプラグインを初期化する関数をトリガーすることです。
したがって、この構造を持っているとしましょう。
ホームページスライダーウィジェット製品の回転子..etc
これらの要素にはそれぞれ独自のコンポーネントがあり、すべてホームページの親コンポーネントの子です。
ここで必要なのは、すべての子コンポーネントと親コンポーネントがいつロードされるかを知ることです。そのため、1つのjquery関数をトリガーして、ページ上のすべてのプラグインを初期化します。
AfterViewInit( https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#afterview )をインポートすることにより、「ngAfterViewInit」ライフサイクルフックを使用します。次のように使用できます。
インストール:
tsd install jquery --save
または
typings install dt~jquery --global --save
利用:
import { Component, AfterViewInit } from '@angular/core';
import * as $ from 'jquery';
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);
}
私が見つけた最も効果的な方法は、ページ/コンポーネントコンストラクター内で時間0のsetTimeoutを使用することです。 Angularがすべての子コンポーネントのロードを完了した後、次の実行サイクルでjQueryを実行しましょう。
export class HomePage {
constructor() {
setTimeout(() => {
// run jQuery stuff here
}, 0);
}
}
NgOnInitメソッド内にsetTimeoutを配置することもうまくいきました。
export class HomePage {
ngOnInit() {
setTimeout(() => {
// run jQuery stuff here
}, 0);
}
}
どう?
_bootstrap(...).then(x => {
...
})
_
それ以外の場合、ルートコンポーネントのngAfterViewInit()
は、要件に一致するライフサイクルフックであると想定しますが、すでにすべてをテストしたと述べています...
更新
ルートコンポーネントのbootstrap()
またはngAfterViewInit()
は、初期ロードにのみ使用できます。後で追加されたコンポーネントの場合、追加されたコンポーネントのngAfterViewInit()
を使用できます。
ここでも同じ問題がありました。私は2つの解決策を見つけましたが、それらは最良ではありません:
1-jQueryプラグインが開始されているかどうかを確認するafterViewCheckedを実装し、変数を使用してその初期化を制御します。 afterViewCheckedが何度も呼び出されるため、これは難しい方法です。
2-ngIfの代わりにhiddenプロパティを使用して、いくつかの要素を非表示に変更しました。 hiddenを使用すると、afterViewInitを使用してすべてのjqueryプラグインを初期化し、オブジェクトが非表示であっても機能させることができます。
ngIfの使用時にsetTimeoutが機能しませんでした。コンテンツが再レンダリングされる前にトリガーされます。
可能な解決策の1つは、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();
});
});
}
こちらもご覧ください