2017-07-25 5 views
0

In angular 2 kann man je nach Komponente CSS Styles laden. Es gibt jedoch keine entsprechende Möglichkeit zum Laden von Skriptdateien. Ich lade gerade alle Skripte auf der Basisseite meiner Einzelseitenanwendungen, aber das führt zu Optimierungsproblemen.Angular 2/4 Skripten dynamisch laden

Was ist der empfohlene Weg zum Laden von Skripten für eine Angular 2/4 Komponente.

+1

welche Skripte? Skripte können nicht mit bestimmten Komponenten verwendet werden, die es in index.html sein muss. –

+0

Wenn Sie JS-Skripte oder Bibliotheken von Drittanbietern laden müssen, versuchen Sie es in Ihrer Anwendung einzubetten, statt es in index.html zu verwenden. Hier ist ein [link] (https : //rahulrsingh09.github.io/AngularConcepts) –

Antwort

1
 Well you can load script dynamically in any component. 

     Here is the solution. 

     1. Create a service in which you'll have js file. 
     Example-script.store.ts 

     interface Scripts { 
      name: string; 
      src: string; 
     } 

     export const ScriptStore: Scripts[] = [ 
      { name: 'moment', src: 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js' }, 
      { name: 'datatables', src: 'https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.js' } 

     ]; 

    2. Now create a service that will load & return the status of the script. 

    Example- script.service.ts 


    import { Injectable } from '@angular/core'; 
    import { ScriptStore } from './script.store'; 

    declare var document: any; 
    declare var jQuery: any; 

    @Injectable() 
    export class Script { 
     public scripts: any = {}; 

     load(...scripts: string[]) { 
     var promises: any[] = []; 
     scripts.forEach((script)=>promises.push(this.loadScript(script))); 
     return Promise.all(promises); 
     } 

     loadScript(name: string) { 
     return new Promise((resolve, reject) => { 
      //resolve if already loaded 
      if (this.scripts[name].loaded) { 
      resolve({script:name, loaded:true, status:'Already Loaded'}); 
      } 
      else{ 
      //load script 
      let script = document.createElement('script'); 
      script.type = 'text/javascript'; 
      script.src = this.scripts[name].src; 
      if(script.readyState) { //IE 
       script.onreadystatechange =() => { 
       if (script.readyState === "loaded" || script.readyState === "complete") { 
        script.onreadystatechange = null; 
        this.scripts[name].loaded = true; 
        resolve({script:name, loaded:true, status:'Loaded'}); 
       } 
       }; 
      } else { //Others 
       script.onload =() => { 
       this.scripts[name].loaded = true; 
       resolve({script:name, loaded:true, status:'Loaded'}); 
       }; 
      } 
      script.onerror = (error: any) => resolve({script:name, loaded:false, status:'Loaded'}); 
      document.getElementsByTagName('head')[0].appendChild(script); 
      } 
     }); 
     } 

     constructor() { 
     ScriptStore.forEach((script: any) => { 
      this.scripts[script.name]={ 
      loaded: false, 
      src: script.src 
      }; 
     }); 
     } 
    } 

3. Now you just to import & call the service. 
Example- 


import- 
import {Script} from './script.service'; (specify the apth where you have created the service) 

Now call service- 

     ngAfterViewInit() { 
     this._script.load('datatables') 
      .then((data:any)=>{ 
       console.log(data,'script loaded') 
      }) 
      .catch((error)=>{ 
     }); 
    } 

Es wird das Skript von 'datatables' dynamisch hinzugefügt.

Dies dient nur Ihrem Zweck, aber es wird auch nur dort geladen, wo es notwendig ist.

+0

Haben Sie eine funktionierende PLNKR dieses Codes? Ich habe es versucht und ich bekomme einen Fehler, dass es _script.load nicht finden kann. –

+0

Haben Sie nicht die PLNKR, aber ich habe Sie. Es scheint, Sie haben das Skript im Konstruktor nicht definiert. Hier ist die Beispiel- Konstruktor ( public _script: Script) { } Dies wird Ihre Fehler beheben. – Kamaal