首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >加载模板dom时angular2模板/钩子中的脚本标签

加载模板dom时angular2模板/钩子中的脚本标签
EN

Stack Overflow用户
提问于 2015-12-08 01:55:59
回答 2查看 21.8K关注 0票数 12

我被卡住了,不知道如何解决我的问题……

简化版:我有一个基于绑定创建ulist的组件,如下所示:

代码语言:javascript
复制
@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。问题是,在普通站点上,ulist后面的脚本标记用于在列表上应用一些jquery魔术。

由于脚本标记是在组件的模板加载完成之前回显出来的,所以jquery调用将找不到模板DOM的元素。将脚本标记放在我的模板中(最后)并不起作用;它似乎只是被忽略了。

代码语言:javascript
复制
<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中了?

EN

回答 2

Stack Overflow用户

发布于 2016-02-23 15:04:57

元件模板中的脚本标记将被删除。解决方法是在ngAfterViewInit()中动态创建脚本标记

另请参阅https://github.com/angular/angular/issues/4903

代码语言:javascript
复制
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()加载脚本。

另请参阅script tag in angular2 template / hook when template dom is loaded

票数 23
EN

Stack Overflow用户

发布于 2017-06-29 07:46:20

我遇到了同样的问题,但另外我不得不加载许多脚本,其中一些可以并行加载,另一些可以串行加载。如果您使用的是TypeScript 2.1 or greater,它具有对async/await的本机支持和到es3/es5的转换,则此解决方案将起作用:

代码语言:javascript
复制
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

代码语言:javascript
复制
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 rejection,您可以尝试在loadScript()函数中使用scriptElement.onerror = reject,但是在这种情况下,我遇到了一些奇怪的行为。如果你想让脚本在任何情况下都保持加载,你可能想要尝试在调用onerror时解析promises。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34140065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档