2017-05-26 18 views
10

Angular 4とCLIを使用してAngularアプリケーションを作成しています。 SkyScanner検索ウィジェットを自分のコンポーネントの1つに追加しようとしています。Angularコンポーネントから外部javascriptファイルを動的にロード

Skyscanner Widget Example

実装の一部は、新しい外部スクリプトを追加する必要があります。

<script src="https://widgets.skyscanner.net/widget-server/js/loader.js" async></script> 

私はこのファイルを参照するための正しい方法を確認していません。スクリプトをindex.htmlファイルに追加すると、ページ全体のリフレッシュが実行されない限り、ウィジェットはロードされません。私は、スクリプトがロード時にDOMを操作しようとしていると仮定し、要素がスクリプトが実行されるときに存在しません。

Skyscannerウィジェットを含むコンポーネントがロードされている場合にのみ、スクリプトをロードする正しい方法は何ですか?

答えて

20

てみてください、それを使うことができますあなたのangular-cli.json

"scripts": ["./src/assets/loader.js",] 

で、あなたの資産フォルダにloader.jsを追加次のように、共通の負荷でスクリプトをロードする:

あなたは

"scripts": ["../src/assets/js/loader.js"] 

ようなスクリプトに宣言しにスカイスキャナーを宣言することができ、角度-cli.jsonその後、

を持っている場合

loadAPI: Promise<any>; 

constructor() {   
    this.loadAPI = new Promise((resolve) => { 
     this.loadScript(); 
     resolve(true); 
    }); 
} 

public loadScript() {   
    var isFound = false; 
    var scripts = document.getElementsByTagName("script") 
    for (var i = 0; i < scripts.length; ++i) { 
     if (scripts[i].getAttribute('src') != null && scripts[i].getAttribute('src').includes("loader")) { 
      isFound = true; 
     } 
    } 

    if (!isFound) { 
     var dynamicScripts = ["https://widgets.skyscanner.net/widget-server/js/loader.js"]; 

     for (var i = 0; i < dynamicScripts .length; i++) { 
      let node = document.createElement('script'); 
      node.src = dynamicScripts [i]; 
      node.type = 'text/javascript'; 
      node.async = false; 
      node.charset = 'utf-8'; 
      document.getElementsByTagName('head')[0].appendChild(node); 
     } 

    } 
} 
+0

これはこれまでのところ最高の答えのようです。ありがとうございました。 loadScriptの呼び出しをコンストラクタに入れるか、ngOnInitを使うのが良いでしょうか? – psych

+0

ngOnInitで試してみることはできませんが、INITで動作する場合は、 –

+0

を置くのに最適な場所ですが、このファイルの読み込みに時間がかかるため、この知識がなくても関数がレンダリングされます。後でそれは役に立たなかった。これを解決する方法。 –

2

、あなたのtypings.d.ts

declare var skyscanner:any; 

にこれを追加し、

skyscanner.load("snippets","2"); 
+0

は、最後の行をい私は(skyscanner.load ...)を追加してコンポーネントに追加しますか?その場合、名前スカイスキャナーを見つけることができないというエラーが表示されます。 – psych

0

あなたは一つのこと

を行うことができますあなたのコンポーネント

のように

declare var skyscanner:any; 

それはそれです!

希望あなたが

+0

私はこのスクリプトをローカルに追加し、それをangular-cli.jsonファイルに含めました。残念ながら、これは動作しません。宣言をコンポーネントに追加することで期待されることを説明できますか? – psych

3

このヘルプは、私はあなたのようにスクリプトをロードするために、独自のディレクティブを作成することができ、この

this.addJsToElement('https://widgets.skyscanner.net/widget-server/js/loader.js').onload =() => { 
     console.log('SkyScanner Tag loaded'); 
} 
0

のようにそれを呼び出し、このコードスニペット

addJsToElement(src: string): HTMLScriptElement { 
    const script = document.createElement('script'); 
    script.type = 'text/javascript'; 
    script.src = src; 
    this.elementRef.nativeElement.appendChild(script); 
    return script; 
    } 

を行われています以下

import { Directive, OnInit, Input } from '@angular/core'; 

@Directive({ 
    selector: '[appLoadScript]' 
}) 
export class LoadScriptDirective implements OnInit{ 

    @Input('script') param: any; 

    ngOnInit() { 
     let node = document.createElement('script'); 
     node.src = this.param; 
     node.type = 'text/javascript'; 
     node.async = false; 
     node.charset = 'utf-8'; 
     document.getElementsByTagName('head')[0].appendChild(node); 
    } 

} 

そして、あなたが動的コンポーネントにはJQueryをロードするために、例えば

<i appLoadScript [script]="'script_file_path'"></i> 

以下のようにあなたのコンポーネントテンプレートのどこにでもそれを使用することができ、あなたのコンポーネントのテンプレートにコードの下に挿入し

<i appLoadScript [script]="'/assets/baker/js/jquery.min.js'"></i> 
関連する問題