2017-05-26 104 views
10

我正在使用Angular 4和CLI創建一個Angular應用程序。我正在嘗試將SkyScanner搜索小部件添加到我的某個組件中。實施動態加載來自Angular組件的外部JavaScript文件

Skyscanner Widget Example

部分需要添加一個新的外部腳本:

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

我不知道的引用此文件的正確方法。如果我將腳本添加到我的index.html文件中,則除非執行完整頁面刷新,否則不會加載小部件。我假設腳本試圖在加載時操作DOM,並且腳本運行時元素不存在。

只有在加載包含Skyscanner小部件的組件時才加載腳本的正確方法是什麼?

回答

20

嘗試以下面的方式加載組件加載腳本:

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

添加loader.js到您的資產文件夾,然後在你的angular-cli.json

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

然後添加到您的typings.d.ts

declare var skyscanner:any; 

,你將能夠使用它

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

是否最後一行我添加(skyscanner.load ...)被添加到組件中?假設是這樣,我看到一個錯誤,說找不到名稱skyscanner。 – psych

0

你可以做一件事

,如果你有角cli.json

,那麼你可以聲明腳本

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

然後聲明在Skyscanner上您的組件

like

declare var skyscanner:any; 

這就是它!

希望這有助於你

+0

我在本地添加了腳本,並將其包含在angular-cli.json文件中。不幸的是,這是行不通的。請你能解釋一下將該聲明添加到組件中的原因是什麼? – psych

3

我已經做了這個代碼片斷

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

然後調用它像這樣

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

您可以創建自己的指令加載腳本低於

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

} 

而且你可以在你的組件模板中的任何地方使用它,如下

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

例如,動態加載的JQuery在您的組件,在組件的模板中插入下面的代碼

<i appLoadScript [script]="'/assets/baker/js/jquery.min.js'"></i> 
相關問題