在 Angular 组件模板中添加脚本标签

新手上路,请多包涵

Angular2 自动从模板中删除 <script> 标签,以阻止人们将此功能用作 “穷人”加载程序

这里的问题是脚本标签目前有更多的用途,而不仅仅是加载代码或其他脚本文件。将来也可能会引入围绕 <script> 标签的更多功能。

当前的一种用途是采用以下格式的 JSON-LD

 <script type="application/ld+json">
{
    "@context":"http://schema.org",
    "@type":"HealthClub",
    ...
}
</script>

通常建议的解决方法是通过 ngAfterViewInit 挂钩 将脚本标签动态添加 到文档中,但这显然不是正确的 ng2 实践并且不会在服务器端工作,JSON-LD 显然需要能够做。

我们是否可以使用任何其他解决方法来在 angular2 模板中包含 <script> 标签(即使标签在浏览器中是惰性的),或者这是框架过于自以为是的情况?如果在angular2中无法解决这种情况,可能还有哪些其他解决方案?

原文由 Ian Belcher 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 550
2 个回答

也许在这里聚会有点晚了,但由于上述答案不适用于 Angular SSR(例如 document is not defined 服务器端或 document.createElement is not a function ),我决定编写一个版本适用于 Angular 4+, 在服务器和浏览器上下文中

组件实现

import { Renderer2, OnInit, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

class MyComponent implements OnInit {

    constructor(
        private _renderer2: Renderer2,
        @Inject(DOCUMENT) private _document: Document
    ) { }

    public ngOnInit() {

        let script = this._renderer2.createElement('script');
        script.type = `application/ld+json`;
        script.text = `
            {
                "@context": "https://schema.org"
                /* your schema.org microdata goes here */
            }
        `;

        this._renderer2.appendChild(this._document.body, script);
    }
}

服务实施

注意:服务不能直接使用 Renderer2 。事实上,渲染元素 应该由 Component 完成。但是,您可能会发现自己处于想要在页面上自动创建 JSON-LD script 标记的情况。例如,一种情况可能是在路线导航更改事件上调用此类功能。因此,我决定添加一个适用于 Service 上下文的版本。

 import { Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

/**
 * Use a Service to automate creation of JSON-LD Microdata.
 */
class MyService {

    constructor(
        @Inject(DOCUMENT) private _document: Document
    ) { }

    /**
     * Set JSON-LD Microdata on the Document Body.
     *
     * @param renderer2             The Angular Renderer
     * @param data                  The data for the JSON-LD script
     * @returns                     Void
     */
    public setJsonLd(renderer2: Renderer2, data: any): void {

        let script = renderer2.createElement('script');
        script.type = 'application/ld+json';
        script.text = `${JSON.stringify(data)}`;

        renderer2.appendChild(this._document.body, script);
    }
}

原文由 Nicky 发布,翻译遵循 CC BY-SA 4.0 许可协议

Angular2 没有向模板添加脚本标签的方法。

使用 require(...) 从组件类加载外部脚本被提到作为一种解决方法(我自己还没有尝试过)

动态添加脚本标签使用

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);
}

另见 angular2:在组件中包含第三方 js 脚本

原文由 Günter Zöchbauer 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题