Добавление тегов скриптов в шаблон углового компонента
Angular2 удаляет <script>
теги автоматически из шаблонов, чтобы остановить людей, использующих эту функцию как "бедняга" погрузчик.
проблема здесь в том, что теги скриптов в настоящее время имеют больше применений, чем просто загрузка кода или других файлов скриптов. Существует вероятность того, что дальнейшая функциональность вокруг <script>
теги будут введены в будущем.
одно текущее использование-JSON-LD, который принимает формат
<script type="application/ld+json">
{
"@context":"http://schema.org",
"@type":"HealthClub",
...
}
</script>
обыкновенно предлагаемая работа - это динамически добавить теги script к документу через ngAfterViewInit
крюк, но это, очевидно, не правильная практика ng2 и не будет работать на стороне сервера, что JSON-LD, очевидно, должен быть в состоянии сделать.
есть ли другие обходные пути, которые мы можем использовать для включения <script>
теги в шаблонах angular2 (даже если тег инертен в браузере) или это случай слишком самоуверенного фреймворка? Какие другие решения могут существовать, если это ситуация не может быть решена в angular2?
4 ответов
может быть, немного поздно на вечеринку здесь, но так как вышеуказанные ответы не работают хорошо с угловой ССР (например,document is not defined
на стороне сервера или document.createElement is not a function
), я решил написать версию, которая работает для Angular 4+,в контексте сервера и браузера:
Реализация Компонента
import { Renderer2, OnInit, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
class MyComponent implements OnInit {
constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _document) {
}
public ngOnInit() {
let s = this._renderer2.createElement('script');
s.type = `application/ld+json`;
s.text = `
{
"@context": "https://schema.org"
/* your schema.org microdata goes here */
}
`;
this._renderer2.appendChild(this._document.body, s);
}
}
Реализация Сервиса
Примечание: службы не могут использовать Renderer2
напрямую. Фактически, элемент рендеринга is предполагается, что выполняется компонентом. Однако вы можете оказаться в ситуации, когда вы хотите автоматизировать создание JSON-LD script
теги на странице. Ситуация может заключаться в вызове такой функции в событиях изменения навигации по маршруту. Поэтому я решил добавить версию, которая работает в Service
контексте.
import { Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
class MyService {
constructor(@Inject(DOCUMENT) private _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 s = renderer2.createElement('script');
s.type = `application/ld+json`;
s.text = `${JSON.stringify(data)}`;
renderer2.appendChild(this._document.body, s);
}
}
нет способа Angular2 добавления тега скрипта в шаблон.
используя require(...)
для загрузки внешних скриптов из класса components был упомянут как обходной путь (сам не пробовал)
для динамического добавления тега script использовать
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 третьей стороны в компоненте
на самом деле
Нет Angular2 путем добавления тега к шаблону.
но вы можете сделать некоторые фишка
в первую очередь вы импортируете AfterViewInit
и ElementRef
из angular2
вот так:
import {Component,AfterViewInit,ElementRef} from 'Angular2/core';
затем вы будете реализовывать их в своем классе так:
export class example1 implements AfterViewInit{}
и вот очень простой javascript DOM трюк, который вы собираетесь сделать
export class example1 implements AfterViewInit{
ngAfterViewInit()
{
var s=document.createElement("script");
s.type="text/javascript";
s.innerHTML="console.log('done');"; //inline script
s.src="path/test.js"; //external script
}
}
следующие работы с угловым 5.2.7:
необходимый импорт являются следующими:
import { Inject, AfterViewInit, ElementRef } from '@angular/core';
import { DOCUMENT } from '@angular/common';
Реализовать AfterViewInit:
export class HeroesComponent implements AfterViewInit {
если ваш компонент реализует более одного интерфейса, разделите их запятыми; например:
export class HeroesComponent implements OnInit, AfterViewInit {
передайте приведенные ниже аргументы конструктору:
constructor(@Inject(DOCUMENT) private document, private elementRef: ElementRef) { }
добавить ngafterviewinit метод просмотра жизненного цикла:
ngAfterViewInit() {
const s = this.document.createElement('script');
s.type = 'text/javascript';
s.src = '//external.script.com/script.js';
const __this = this; //to store the current instance to call
//afterScriptAdded function on onload event of
//script.
s.onload = function () { __this.afterScriptAdded(); };
this.elementRef.nativeElement.appendChild(s);
}
добавить элемент afterScriptAdded функция.
эта функция будет вызвана после успешной загрузки внешнего скрипта. Таким образом, свойства или функции, которые вы хотите использовать из внешнего js, будут доступны в теле этой функции.
afterScriptAdded() {
const params= {
width: '350px',
height: '420px',
};
if (typeof (window['functionFromExternalScript']) === 'function') {
window['functionFromExternalScript'](params);
}
}