当模板dom被加载时,在angular2模板/钩子中的脚本标记
我相当卡住,不知道如何解决我的问题…
简化:我有一个基于绑定创buildulist的组件,如下所示:
@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 } }
组件select器/主机embedded在由PHP回显的普通htmlstream中,用于replace预定义的ulist。 问题是,在正常的网站上,ulist之后的脚本标签被用来在列表上应用一些jquery魔术。
由于脚本标记在我的组件的模板加载完成之前被回显,所以jquery调用将不会find我的模板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()
。
所以我的问题是,当我不知道我的模板是否已经完成创build,我怎么能实现在我的模板DOM上调用jQuery。 onload处理程序在我的组件模板中定义时不起作用。
我已经阅读了关于AfterViewInit,但我有点不知所措。 有人能把我推向正确的方向吗?
我怎样才能找出什么时候我的组件的模板已经完全插入到“主”DOM?
组件模板中的脚本标签被删除。 解决方法是在ngAfterViewInit()
dynamic创build脚本标记
另见https://github.com/angular/angular/issues/4903
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()
来加载脚本。
加载模板dom时,请参阅angular2模板/钩子中的脚本标记
我遇到了同样的问题,但另外我不得不加载一些脚本,其中一些脚本可以并行加载,另外一些脚本可以加载。 如果您使用的TypeScript 2.1或更高版本 ,本解决scheme将工作,其中本机支持asynchronous/等待和转换到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") }
注意:对于承诺拒绝,您可以尝试在loadScript()
函数中使用scriptElement.onerror = reject
,但是在这种情况下,我遇到了一些古怪的行为。 如果你想让脚本继续加载,你可能需要尝试解决onerror被调用时的承诺。