私はかなり立ち往生していて、私の問題を解決する方法がわかりません...
簡略化:次のように、バインディングに基づいてulistを作成するコンポーネントがあります。
_@Component({
selector: "template",
template: `
<ul>
<li *ng-for="#challenge of jobs.challenges">{{challenge}}</li>
</ul>
`})
export class JobTemplate{
jobs: Jobs;
constructor(jobs:Jobs){
this.jobs = jobs
}
}
_
コンポーネントセレクター/ホストは、phpによってエコーされる通常のhtmlフローに埋め込まれ、事前定義されたulistを置き換えるために使用されます。問題は、通常のサイトでは、リストにjqueryマジックを適用するためにulistの後のスクリプトタグが使用されていることです。
スクリプトタグは、コンポーネントのテンプレートの読み込みが完了する前にエコー出力されるため、jquery呼び出しでは、テンプレートDOMの要素が見つかりません。 (最後に)テンプレート内にスクリプトタグを配置しても機能しません。単に無視されるようです。
_<ul>
<a><li *ng-for="#challenge of jobs.challenges">{{challenge}}</li></a>
</ul>
<script>
$("ul a").on("click", function (event)
{
var parent = $(this).parent();
if(parent.hasClass('active'))
....slideToggle("normal");
else
....
});
</script>
_
また、サイトは基盤フレームワークを使用しており、新しい要素がページに追加されるたびに(たとえば、外部で更新されているコンポーネントのバインディングを通じて)、$(document).foundation()
を呼び出す必要があります。
だから私の質問は、テンプレートの作成が完了したかどうかわからないときに、テンプレートDOMでjqueryを呼び出すにはどうすればよいですか?コンポーネントテンプレートで定義されている場合、onloadハンドラーも機能しません。
私はAfterViewInitについて読みましたが、それに圧倒されています。誰かが私を正しい方向に押してくれませんか?
コンポーネントのテンプレートが「メイン」DOMに完全に挿入されたことを確認するにはどうすればよいですか?
コンポーネントテンプレートのスクリプトタグは削除されました。回避策は、ngAfterViewInit()
でスクリプトタグを動的に作成することです
参照 https://github.com/angular/angular/issues/49
_constructor(private elementRef:ElementRef) {};
ngAfterViewInit() {
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "http://somedomain.com/somescript";
this.elementRef.nativeElement.appendChild(s);
}
_
参照 https://stackoverflow.com/a/9413803/217408
より良い方法は、require()
を使用してスクリプトをロードすることです。
同じ問題が発生しましたが、さらに、いくつかのスクリプトをロードする必要があり、その一部は並列にロードでき、他のスクリプトは直列にロードできました。このソリューションは、 TypeScript 2.1以降 を使用している場合に機能します。これには、 async/await のネイティブサポートとES3 /へのトランスパイルがあります。 ES5:
_async ngAfterViewInit() {
await this.loadScript("http://sub.domain.tld/first-script.js")
await this.loadScript("http://sub.domain.tld/second-script.js")
}
private loadScript(scriptUrl: string) {
return new Promise((resolve, reject) => {
const scriptElement = document.createElement('script')
scriptElement.src = scriptUrl
scriptElement.onload = resolve
document.body.appendChild(scriptElement)
})
}
_
並行してロードできるスクリプトの場合、 Promise.all を利用できます。
_async ngAfterViewInit() {
await Promise.all([
this.loadScript("http://sub.domain.tld/first-parallel.js"),
this.loadScript("http://sub.domain.tld/second-parallel.js")
])
await this.loadScript("http://sub.domain.tld/after-parallel.js")
}
_
注:promiseの拒否については、loadScript()
関数で_scriptElement.onerror = reject
_を使用して試すことができますが、この状況での風変わりな動作。スクリプトのロードを継続したい場合は、onerrorが呼び出されたときにプロミスを解決してみてください。