Angular2は、テンプレートから<script>
タグを自動的に削除して、この機能を "poor's man" loader として使用しているユーザーを停止します。
ここでの問題は、スクリプトタグには現在、コードや他のスクリプトファイルを読み込むだけでなく、より多くの用途があるということです。 <script>
タグに関するさらなる機能が将来導入される可能性もあります。
現在使用されているのは、次の形式のJSON-LDです
<script type="application/ld+json">
{
"@context":"http://schema.org",
"@type":"HealthClub",
...
}
</script>
一般的に推奨される回避策は、 動的にスクリプトタグを追加 をngAfterViewInit
フックを介してドキュメントに追加することですが、これは明らかに適切なng2プラクティスではなく、サーバー側では動作しません。できる必要があります。
Angular2テンプレートに<script>
タグを含めるために使用できる他の回避策はありますか(タグがブラウザ内で不活性である場合でも)、またはフレームワークが過度に考えられている場合ですか?この状況をangular2で解決できない場合、他にどのようなソリューションが存在する可能性がありますか?
ここでのパーティーに少し遅れるかもしれませんが、上記の回答は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
を直接使用できません。実際、要素のレンダリングコンポーネントによって実行されることになっています。ただし、ページ上の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);
}
}
スクリプトタグをテンプレートに追加する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スクリプトをコンポーネントに含める も参照してください
import { Inject, AfterViewInit, ElementRef } from '@angular/core';
import { DOCUMENT } from '@angular/common';
export class HeroesComponent implements AfterViewInit {
コンポーネントが複数のインターフェイスを実装している場合は、コンマで区切ります。例えば:
export class HeroesComponent implements OnInit, AfterViewInit {
constructor(@Inject(DOCUMENT) private document, private elementRef: ElementRef) { }
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);
}
この関数は、外部スクリプトが正常にロードされた後に呼び出されます。したがって、外部jsから使用するプロパティまたは関数は、この関数の本体でアクセスされます。
afterScriptAdded() {
const params= {
width: '350px',
height: '420px',
};
if (typeof (window['functionFromExternalScript']) === 'function') {
window['functionFromExternalScript'](params);
}
}
実際ありませんAngular2テンプレートにscript tagを追加する方法。しかし、あなたはいくつかを行うことができますトリックまず第一にこのようにangle2からAfterViewInit
とElementRef
をインポートします:
import {Component,AfterViewInit,ElementRef} from 'Angular2/core';
thenあなたはそのようにあなたのクラスにそれらを実装します:
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
}
}