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

标签 javascript angular json-ld angular2-universal

Angular2 删除了 <script>从模板中自动标记以阻止人们将此功能用作 "poor's man" loader .

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

目前的一个用途是采用格式的 JSON-LD

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

通常建议的解决方法是 dynamically add script tags通过 ngAfterViewInit 到文件钩子(Hook),但这显然不是正确的 ng2 实践,并且不会在服务器端工作,而 JSON-LD 显然需要能够做到这一点。

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

最佳答案

这里的派对可能有点晚了,但由于上述答案不适用于 Angular SSR(例如 document is not defined 服务器端或 document.createElement 不是函数),我决定编写一个适用于 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。事实上,呈现元素应该由组件完成。但是,您可能会发现自己处于想要在页面上自动创建 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);
    }
}

关于javascript - 在 Angular 组件模板中添加脚本标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38088996/

相关文章:

javascript - Typescript - 导入带有路径别名的类失败

Javascript - 变量缺失

Angular 2 CLI 升级到最新版本,现在 ng serve 给我错误

javascript - 如何获取PDF文件的页数?

html - JSON-LD 和元标记

java - JSON-LD 空白节点到 Apache Jena 中的嵌套对象

javascript - 使用 emscripten 在 JavaScript 中分配 C 结构体

javascript - 这是否被视为 POST 或 GET 请求?

html - 添加CSS类时如何强制Angular更新元素CSS

javascript - application/ld+json与javascript数据交换