कोणीय में गतिशील लिपियों को कैसे लोड किया जाए?


150

मेरे पास यह मॉड्यूल है जो अतिरिक्त लॉजिक के साथ बाहरी लाइब्रेरी को एक साथ जोड़े बिना <script>टैग को सीधे index.html में जोड़ देता है :

import 'http://external.com/path/file.js'
//import '../js/file.js'

@Component({
    selector: 'my-app',
    template: `
        <script src="http://iknow.com/this/does/not/work/either/file.js"></script>
        <div>Template</div>`
})
export class MyAppComponent {...}

मैं नोटिस करता हूं importकि ES6 युक्ति स्थिर है और रनटाइम के बजाय टाइपस्क्रिप्ट ट्रांसप्लिंग के दौरान हल हो गई है।

वैसे भी इसे कॉन्फ़िगर करने योग्य बनाने के लिए इसलिए CD. या स्थानीय फ़ोल्डर से फ़ाइल। Js लोड हो रही होगी? एक स्क्रिप्ट को गतिशील रूप से लोड करने के लिए कोणीय 2 कैसे बताएं?


जवाबों:


61

यदि आप system.js का उपयोग कर रहे हैं, तो आप System.import()रनटाइम पर उपयोग कर सकते हैं :

export class MyAppComponent {
  constructor(){
    System.import('path/to/your/module').then(refToLoadedModule => {
      refToLoadedModule.someFunction();
    }
  );
}

यदि आप वेबपैक का उपयोग कर रहे हैं, तो आप इसके मजबूत कोड विभाजन समर्थन का पूरा लाभ उठा सकते हैं require.ensure:

export class MyAppComponent {
  constructor() {
     require.ensure(['path/to/your/module'], require => {
        let yourModule = require('path/to/your/module');
        yourModule.someFunction();
     }); 
  }
}

1
ऐसा लगता है जैसे मुझे विशेष रूप से घटक में मॉड्यूल लोडर का उपयोग करने की आवश्यकता है। Systemमुझे लगता है कि लोडर का भविष्य ठीक है।
CallMeLaNN

6
TypeScript Plugin for Sublime TextSystemटाइपस्क्रिप्ट कोड में खुश नहीं है : Cannot find name 'System'लेकिन ट्रांसपिलिंग और रनिंग के दौरान कोई त्रुटि नहीं है। दोनों Angular2और Systemस्क्रिप्ट फ़ाइल में पहले से ही जोड़ा गया है index.html। वैसे भी करने के लिए और प्लगइन को खुश करने के? importSystem
CallMeLaNN

1
लेकिन क्या होगा अगर आप system.js का उपयोग नहीं कर रहे हैं!
मुराफ सूसली

2
@ ड्रूमोर मुझे याद नहीं है कि मैंने ऐसा क्यों कहा, require()/ importआपके जवाब के रूप में अब ठीक काम करना चाहिए, +1
मुराफ सूसली

9
क्या मैं इन विकल्पों को बता सकता हूं इंटरनेट पर स्क्रिप्ट के लिए काम नहीं करता, सिर्फ स्थानीय फ़ाइलों के लिए। यह पूछे जाने वाले मूल प्रश्न का उत्तर नहीं देता है।
विली

139

आप अपने कोणीय प्रोजेक्ट में जेएस लिपियों और पुस्तकालयों को मांग पर गतिशील रूप से लोड करने के लिए निम्नलिखित तकनीक का उपयोग कर सकते हैं।

script.store.ts में स्क्रिप्ट का पथ स्थानीय या दूरस्थ सर्वर पर होगा और एक नाम जिसका उपयोग स्क्रिप्ट को लोड करने के लिए किया जाएगा

 interface Scripts {
    name: string;
    src: string;
}  
export const ScriptStore: Scripts[] = [
    {name: 'filepicker', src: 'https://api.filestackapi.com/filestack.js'},
    {name: 'rangeSlider', src: '../../../assets/js/ion.rangeSlider.min.js'}
];

script.service.ts एक इंजेक्टेबल सेवा है जो स्क्रिप्ट की लोडिंग को संभालती है, script.service.tsजैसा है वैसा ही कॉपी करें

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

declare var document: any;

@Injectable()
export class ScriptService {

private scripts: any = {};

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

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

}

ScriptServiceजहाँ भी आपको इसकी आवश्यकता हो, इसे इंजेक्ट करें और इस तरह से js lib लोड करें

this.script.load('filepicker', 'rangeSlider').then(data => {
    console.log('script loaded ', data);
}).catch(error => console.log(error));

7
यह शानदार ढंग से काम करता है। प्रारंभिक लोड आकार से 1 एमबी अधिक है - मेरे पास बहुत सारे पुस्तकालय हैं!
Our_Benefactors

2
लगता है जैसे मैंने बहुत जल्द बोल दिया। यह समाधान iOS सफारी में काम नहीं करता है।
Our_Benefactors

स्क्रिप्ट लोड करने के बाद जाँच करें कि क्या यह आपके डोम के प्रमुख के पास है
राहुल कुमार

शायद मैं सही ढंग से इंजेक्शन नहीं कर रहा हूँ, लेकिन मैं हो रही हैthis.script.load is not a function
Towelie

धन्यवाद। यह काम करता है, लेकिन मुझे मेरी स्क्रिप्ट (एक पृष्ठभूमि एनीमेशन) हर दूसरे घटक में लोड हो रही है। मैं चाहता हूं कि इसे केवल मेरे पहले घटक पर लोड किया जाए (यह एक लॉगिन पृष्ठ है)। उसे हासिल करने के लिए मैं क्या कर सकता हूं? धन्यवाद
जोएल Azevedo

47

यह काम कर सकता है। यह कोड डायनामिक रूप से क्लिक की गई HTML फ़ाइल में <script>टैग को जोड़ता है head

const url = 'http://iknow.com/this/does/not/work/either/file.js';

export class MyAppComponent {
    loadAPI: Promise<any>;

    public buttonClicked() {
        this.loadAPI = new Promise((resolve) => {
            console.log('resolving promise...');
            this.loadScript();
        });
    }

    public loadScript() {
        console.log('preparing to load...')
        let node = document.createElement('script');
        node.src = url;
        node.type = 'text/javascript';
        node.async = true;
        node.charset = 'utf-8';
        document.getElementsByTagName('head')[0].appendChild(node);
    }
}

1
थैंक्स मैन ने मेरे लिए काम किया। अब आप इसे पृष्ठ लोड पर भी nagonit विधि का उपयोग करके लोड कर सकते हैं। इसलिए बटन क्लिक की आवश्यकता नहीं है।
नीरज

मैं उसी तरह का उपयोग कर रहा हूं .. लेकिन मेरे लिए काम नहीं किया। क्या आप कृपया मेरी मदद कर सकते हैं? this.loadJs ("javascriptfile path"); सार्वजनिक भारज (फ़ाइल) {let नोड = document.createElement ('स्क्रिप्ट'); नोड। src = फ़ाइल; नोड.प्रकार = 'पाठ / जावास्क्रिप्ट'; नोड.संकट = सच; नोड.हार्सेट = 'यूटीएफ -8'; document.getElementsByTagName ( 'सिर') [0] .appendChild (नोड); }
मितेश शाह

क्या आप इसे क्लिक या पेज लोड करने की कोशिश कर रहे हैं? क्या आप हमें परिणाम या त्रुटि के बारे में अधिक बता सकते हैं?
एनजी-डेरेन

हैलो, मैंने इसे लागू करने और ठीक काम करने की कोशिश की है लेकिन new Promiseहल नहीं किया गया है। क्या आप मुझे बता सकते हैं कि मुझे Promiseकुछ भी आयात करना होगा?
user3145373

नमस्ते, मैं कुछ विशेष आयात नहीं किया जब मैं वादा का उपयोग करें।
एनजी-डेरेन

23

मैंने @Arul kumars उत्तर को संशोधित किया है, ताकि इसके बजाय वेधशाला का उपयोग करें:

import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { Observer } from "rxjs/Observer";

@Injectable()
export class ScriptLoaderService {
    private scripts: ScriptModel[] = [];

    public load(script: ScriptModel): Observable<ScriptModel> {
        return new Observable<ScriptModel>((observer: Observer<ScriptModel>) => {
            var existingScript = this.scripts.find(s => s.name == script.name);

            // Complete if already loaded
            if (existingScript && existingScript.loaded) {
                observer.next(existingScript);
                observer.complete();
            }
            else {
                // Add the script
                this.scripts = [...this.scripts, script];

                // Load the script
                let scriptElement = document.createElement("script");
                scriptElement.type = "text/javascript";
                scriptElement.src = script.src;

                scriptElement.onload = () => {
                    script.loaded = true;
                    observer.next(script);
                    observer.complete();
                };

                scriptElement.onerror = (error: any) => {
                    observer.error("Couldn't load script " + script.src);
                };

                document.getElementsByTagName('body')[0].appendChild(scriptElement);
            }
        });
    }
}

export interface ScriptModel {
    name: string,
    src: string,
    loaded: boolean
}

1
आप सेट भूल asyncकरने के लिए true
विल

मेरे पास एक प्रश्न है, जब हम स्क्रिप्ट को जोड़ते हैं और मार्गों के बीच नेविगेट करते हैं, मैं कहता हूं कि मैंने स्क्रिप्ट को घर पर लोड किया और ब्राउज़ करें और घर वापस लौटा, क्या वर्तमान स्क्रिप्ट को सुदृढ़ करने का कोई तरीका है? इसका मतलब है कि मैं पहले से लोड किए गए को हटाकर फिर से लोड करना चाहूंगा? बहुत बहुत धन्यवाद
d123546

@ d123546 हां, यदि आप चाहते हैं कि यह संभव है। लेकिन आपको कुछ तर्क लिखना होगा जो स्क्रिप्ट टैग को हटा देता है। एक नज़र यहाँ है: stackoverflow.com/questions/14708189/…
जोएल

धन्यवाद जोएल, लेकिन क्या किसी तरह से स्क्रिप्ट द्वारा शुरू किए गए कार्यों को हटाने का एक तरीका है? वर्तमान में Im को मेरे angular4 प्रोजेक्ट में समस्या का सामना करना पड़ रहा है, क्योंकि Im लोडिंग स्क्रिप्ट जो jquery स्लाइडर को इनिशियलाइज़ करती है, इसलिए जब पहला रूट इसे ठीक से प्रदर्शित करता है, लेकिन तब जब मैं दूसरे रूट पर जाता हूं और अपने रूट पर वापस जाता हूं, तो स्क्रिप्ट दो बार लोड होती है और स्लाइडर अब लोड नहीं हो रहा है :( क्या आप मुझे इस पर सलाह दे सकते हैं
d123546

1
लाइन में कोई त्रुटि है private scripts: {ScriptModel}[] = [];। यह होना चाहिएprivate scripts: ScriptModel[] = [];
क्रिस हैन्स

20

फिर भी एक अन्य विकल्प उस मामले के लिए scriptjsपैकेज का उपयोग करना होगा जो

आपको किसी भी URL से स्क्रिप्ट संसाधनों को ऑन-डिमांड लोड करने की अनुमति देता है

उदाहरण

पैकेज स्थापित करें:

npm i scriptjs

और इसके लिए परिभाषाएँ टाइप करेंscriptjs :

npm install --save @types/scriptjs

फिर आयात $script.get()विधि:

import { get } from 'scriptjs';

और अंत में स्क्रिप्ट संसाधन लोड करें, हमारे मामले में Google मैप्स लाइब्रेरी:

export class AppComponent implements OnInit {
  ngOnInit() {
    get("https://maps.googleapis.com/maps/api/js?key=", () => {
        //Google Maps library has been loaded...
    });
  }
}

डेमो


साझा करने के लिए धन्यवाद, लेकिन async defer की तरह url के साथ अतिरिक्त संपत्ति कैसे जोड़ सकते हैं ?? क्या आप मुझे बता सकते हैं कि लाइब्रेरी के ऊपर इस स्क्रिप्ट को कैसे लोड किया जाए? <script type = 'text / javascript' src = ' bing.com/api/maps/mapcontrol?branch=release ' async defer> </ script>
पुष्कर राठौड़

चूँकि विषय पंक्ति समान है इसलिए मैं यहाँ केवल उत्तर दे रहा हूँ
पुष्कर राठौड़

महान, लेकिन npm स्थापित के बजाय --save @ प्रकार / scriptjs, यह npm स्थापित होना चाहिए - save-dev @ प्रकार / scriptjs (या सिर्फ npm i -D @ प्रकार / scriptjs)
Youness Houdn

18

आप अपनी फ़ाइल में गतिशील रूप से कई स्क्रिप्ट लोड कर सकते हैं component.ts:

 loadScripts() {
    const dynamicScripts = [
     'https://platform.twitter.com/widgets.js',
     '../../../assets/js/dummyjs.min.js'
    ];
    for (let i = 0; i < dynamicScripts.length; i++) {
      const 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);
    }
  }

और कंस्ट्रक्टर के अंदर इस विधि को कॉल करें,

constructor() {
    this.loadScripts();
}

नोट: अधिक स्क्रिप्ट को गतिशील रूप से लोड करने के लिए, उन्हें dynamicScriptsसरणी में जोड़ें ।


3
मुझे कहना है, यह सरल दिखता है, लेकिन अच्छी तरह से काम करता है, बहुत आसान है :-) लागू करने के लिए
पियरे

3
इस प्रकार के स्क्रिप्ट इंजेक्शन के साथ समस्या यह है कि चूंकि एंगुलर एक एसपीए है, इसलिए यह स्क्रिप्ट मूल रूप से DOM से स्क्रिप्ट टैग को हटाने के बाद भी ब्राउज़र कैश पर रहती है।
j4rey

1
बहुत बढ़िया जवाब! मेरा दिन सहेजा गया, यह 6 और 7 एंगुलर के साथ काम करता है!
नादेशान हेराथ

बाह्य js में डेटा भेजने के लिए और बाहरी js से डेटा प्राप्त करने के लिए, इस फ़ंक्शन को app.component.ts पर कॉल करें और किसी भी सुविधा स्तर के मॉड्यूल के घटक: डिक्लेयर var d3Sankey का उपयोग करें। यह काम कर रहा है।
ग्नगनपथ

5

मैंने इस कोड स्निपेट को नए रेंडरर एपी के साथ किया है

 constructor(private renderer: Renderer2){}

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

और फिर इसे इस तरह से कॉल करें

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

StackBlitz


4

मेरे पास स्क्रिप्ट को गतिशील रूप से लोड करने का एक अच्छा तरीका है! अब मैं अपने प्रोजेक्ट में ng6, echarts4 (> 700Kb), ngx-echarts3 का उपयोग करता हूं। जब मैं ngx-echarts के डॉक्स द्वारा उनका उपयोग करता हूं, तो मुझे angular.json: "script": ["./ नोड_modules / echarts / dist / echarts.min.js] में आयात echarts की आवश्यकता होती है। इस प्रकार लॉगिन मॉड्यूल, पेज में स्क्रिप्ट लोड करते समय। .js, यह बड़ी फाइल है! मैं यह नहीं चाहता।

तो, मुझे लगता है कि कोणीय प्रत्येक मॉड्यूल को एक फ़ाइल के रूप में लोड करता है, मैं जेएस को प्रीलोड करने के लिए एक राउटर रिवाल्वर सम्मिलित कर सकता हूं, फिर मॉड्यूल लोड करना शुरू कर सकता हूं!

// PreloadScriptResolver.service.js

/**动态加载js的服务 */
@Injectable({
  providedIn: 'root'
})
export class PreloadScriptResolver implements Resolve<IPreloadScriptResult[]> {
  // Here import all dynamically js file
  private scripts: any = {
    echarts: { loaded: false, src: "assets/lib/echarts.min.js" }
  };
  constructor() { }
  load(...scripts: string[]) {
    const promises = scripts.map(script => this.loadScript(script));
    return Promise.all(promises);
  }
  loadScript(name: string): Promise<IPreloadScriptResult> {
    return new Promise((resolve, reject) => {
      if (this.scripts[name].loaded) {
        resolve({ script: name, loaded: true, status: 'Already Loaded' });
      } else {
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = this.scripts[name].src;
        script.onload = () => {
          this.scripts[name].loaded = true;
          resolve({ script: name, loaded: true, status: 'Loaded' });
        };
        script.onerror = (error: any) => reject({ script: name, loaded: false, status: 'Loaded Error:' + error.toString() });
        document.head.appendChild(script);
      }
    });
  }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<IPreloadScriptResult[]> {
   return this.load(...route.routeConfig.data.preloadScripts);
  }
}

फिर सबमॉडुले-रूटिंगमॉडल.ट में Script इस PreloadScriptResolver को आयात करें:

const routes: Routes = [
  {
    path: "",
    component: DashboardComponent,
    canActivate: [AuthGuardService],
    canActivateChild: [AuthGuardService],
    resolve: {
      preloadScripts: PreloadScriptResolver
    },
    data: {
      preloadScripts: ["echarts"]  // important!
    },
    children: [.....]
}

यह कोड अच्छी तरह से काम करता है, और इसके वादे हैं: जेएस फ़ाइल लोड होने के बाद, फिर मॉड्यूल लोड करना शुरू करते हैं! यह रिज़ॉल्वर कई राउटर में उपयोग कर सकता है


क्या आप कृपया IPreloadScriptResult इंटरफ़ेस का कोड साझा कर सकते हैं?
मेहुल भलाला

3

एक कोणीय सार्वभौमिक समाधान; मुझे वीडियो चलाने के लिए स्क्रिप्ट लोड करने से पहले पृष्ठ पर किसी विशेष तत्व की प्रतीक्षा करने की आवश्यकता थी।

import {Inject, Injectable, PLATFORM_ID} from '@angular/core';
import {isPlatformBrowser} from "@angular/common";

@Injectable({
  providedIn: 'root'
})
export class ScriptLoaderService {

  constructor(
    @Inject(PLATFORM_ID) private platformId: Object,
  ) {
  }

  load(scriptUrl: string) {
    if (isPlatformBrowser(this.platformId)) {
      let node: any = document.createElement('script');
      node.src = scriptUrl;
      node.type = 'text/javascript';
      node.async = true;
      node.charset = 'utf-8';
      document.getElementsByTagName('head')[0].appendChild(node);
    }
  }
}

1
यह किसी तरह से बौना लगता है
मुस्तफा

2

@ राहुल-कुमार का समाधान मेरे लिए अच्छा काम करता है, लेकिन मैं अपनी जावास्क्रिप्ट फ़ंक्शन को अपनी टाइपस्क्रिप्ट में कॉल करना चाहता था

foo.myFunctions() // works in browser console, but foo can't be used in typescript file

मैंने इसे अपनी टाइपस्क्रिप्ट में घोषित करके तय किया:

import { Component } from '@angular/core';
import { ScriptService } from './script.service';
declare var foo;

और अब, मैं अपने टाइपक्रिप्ट फ़ाइल में कहीं भी फू को कॉल कर सकता हूं


अगर मैं कई स्क्रिप्ट foo, foo1, foo2 आयात करता हूं और मैं निष्पादन के समय के दौरान ही जानता हूं कि घोषणा को गतिशील रूप से कैसे किया जाए?
नत्रयान

2

मेरे मामले में, मैंने उपरोक्त तकनीक का उपयोग करके दोनों jsऔर css visjsफ़ाइलों को लोड किया है - जो बहुत अच्छा काम करता है। मैं नए फ़ंक्शन को कॉल करता हूंngOnInit()

नोट: मैंइसे केवलhtml टेम्पलेट फ़ाइल में टैगऔरटैगजोड़कर लोड नहीं कर सका।<script><link>

loadVisJsScript() {
  console.log('Loading visjs js/css files...');
  let script = document.createElement('script');
  script.src = "../../assets/vis/vis.min.js";
  script.type = 'text/javascript';
  script.async = true;
  script.charset = 'utf-8';
  document.getElementsByTagName('head')[0].appendChild(script);    
	
  let link = document.createElement("link");
  link.type = "stylesheet";
  link.href = "../../assets/vis/vis.min.css";
  document.getElementsByTagName('head')[0].appendChild(link);    
}


मैं सीएसएस फ़ाइल को एक बाहरी वेब स्रोत से लोड करना चाहता हूं। वर्तमान में, मुझे यह कहते हुए त्रुटि हो रही है कि "स्थानीय संसाधन लोड करने की अनुमति नहीं है" .. कृपया सुझाव दें।
करण

मैंने इस तरह से कोशिश की। यह लिपियों की फ़ाइलों के लिए अच्छी तरह से काम करने के बावजूद, यह
स्टाइल्सशीट्स के

2

नमस्ते आप कोड की कुछ पंक्तियों के साथ Renderer2 और elementRef का उपयोग कर सकते हैं:

constructor(private readonly elementRef: ElementRef,
          private renderer: Renderer2) {
}
ngOnInit() {
 const script = this.renderer.createElement('script');
 script.src = 'http://iknow.com/this/does/not/work/either/file.js';
 script.onload = () => {
   console.log('script loaded');
   initFile();
 };
 this.renderer.appendChild(this.elementRef.nativeElement, script);
}

onloadसमारोह स्क्रिप्ट कार्यों के बाद स्क्रिप्ट भरी हुई है कॉल करने के लिए इस्तेमाल किया जा सकता है, इस (आप ngOnInit में कॉल करने के लिए है, तो बहुत उपयोगी है)


1

@ d123546 मैंने उसी मुद्दे का सामना किया और इसे इस तरह के घटक में ngAfterContentInit (Lifecycle Hook) का उपयोग करके अब काम कर रहा हूं:

import { Component, OnInit, AfterContentInit } from '@angular/core';
import { Router } from '@angular/router';
import { ScriptService } from '../../script.service';

@Component({
    selector: 'app-players-list',
    templateUrl: './players-list.component.html',
    styleUrls: ['./players-list.component.css'],
    providers: [ ScriptService ]
})
export class PlayersListComponent implements OnInit, AfterContentInit {

constructor(private router: Router, private script: ScriptService) {
}

ngOnInit() {
}

ngAfterContentInit() {
    this.script.load('filepicker', 'rangeSlider').then(data => {
    console.log('script loaded ', data);
    }).catch(error => console.log(error));
}

1
import { Injectable } from '@angular/core';
import * as $ from 'jquery';

interface Script {
    src: string;
    loaded: boolean;
}

@Injectable()
export class ScriptLoaderService {
    public _scripts: Script[] = [];

    /**
     * @deprecated
     * @param tag
     * @param {string} scripts
     * @returns {Promise<any[]>}
     */
    load(tag, ...scripts: string[]) {
        scripts.forEach((src: string) => {
            if (!this._scripts[src]) {
                this._scripts[src] = { src: src, loaded: false };
            }
        });

        const promises: any[] = [];
        scripts.forEach(src => promises.push(this.loadScript(tag, src)));

        return Promise.all(promises);
    }

    /**
     * Lazy load list of scripts
     * @param tag
     * @param scripts
     * @param loadOnce
     * @returns {Promise<any[]>}
     */
    loadScripts(tag, scripts, loadOnce?: boolean) {
        debugger;
        loadOnce = loadOnce || false;

        scripts.forEach((script: string) => {
            if (!this._scripts[script]) {
                this._scripts[script] = { src: script, loaded: false };
            }
        });

        const promises: any[] = [];
        scripts.forEach(script => promises.push(this.loadScript(tag, script, loadOnce)));

        return Promise.all(promises);
    }

    /**
     * Lazy load a single script
     * @param tag
     * @param {string} src
     * @param loadOnce
     * @returns {Promise<any>}
     */
    loadScript(tag, src: string, loadOnce?: boolean) {
        debugger;
        loadOnce = loadOnce || false;

        if (!this._scripts[src]) {
            this._scripts[src] = { src: src, loaded: false };
        }

        return new Promise((resolve, _reject) => {
            // resolve if already loaded
            if (this._scripts[src].loaded && loadOnce) {
                resolve({ src: src, loaded: true });
            } else {
                // load script tag
                const scriptTag = $('<script/>')
                    .attr('type', 'text/javascript')
                    .attr('src', this._scripts[src].src);

                $(tag).append(scriptTag);

                this._scripts[src] = { src: src, loaded: true };
                resolve({ src: src, loaded: true });
            }
        });
    }

    reloadOnSessionChange() {
        window.addEventListener('storage', function(data) {
            if (data['key'] === 'token' && data['oldValue'] == null && data['newValue']) {
                document.location.reload();
            }
        });
    }
}

0

एक नमूना हो सकता है

script-loader.service.ts फ़ाइल

import {Injectable} from '@angular/core';
import * as $ from 'jquery';

declare let document: any;

interface Script {
  src: string;
  loaded: boolean;
}

@Injectable()
export class ScriptLoaderService {
public _scripts: Script[] = [];

/**
* @deprecated
* @param tag
* @param {string} scripts
* @returns {Promise<any[]>}
*/
load(tag, ...scripts: string[]) {
scripts.forEach((src: string) => {
  if (!this._scripts[src]) {
    this._scripts[src] = {src: src, loaded: false};
  }
});

let promises: any[] = [];
scripts.forEach((src) => promises.push(this.loadScript(tag, src)));

return Promise.all(promises);
}

 /**
 * Lazy load list of scripts
 * @param tag
 * @param scripts
 * @param loadOnce
 * @returns {Promise<any[]>}
 */
loadScripts(tag, scripts, loadOnce?: boolean) {
loadOnce = loadOnce || false;

scripts.forEach((script: string) => {
  if (!this._scripts[script]) {
    this._scripts[script] = {src: script, loaded: false};
  }
});

let promises: any[] = [];
scripts.forEach(
    (script) => promises.push(this.loadScript(tag, script, loadOnce)));

return Promise.all(promises);
}

/**
 * Lazy load a single script
 * @param tag
 * @param {string} src
 * @param loadOnce
 * @returns {Promise<any>}
 */
loadScript(tag, src: string, loadOnce?: boolean) {
loadOnce = loadOnce || false;

if (!this._scripts[src]) {
  this._scripts[src] = {src: src, loaded: false};
}

return new Promise((resolve, reject) => {
  // resolve if already loaded
  if (this._scripts[src].loaded && loadOnce) {
    resolve({src: src, loaded: true});
  }
  else {
    // load script tag
    let scriptTag = $('<script/>').
        attr('type', 'text/javascript').
        attr('src', this._scripts[src].src);

    $(tag).append(scriptTag);

    this._scripts[src] = {src: src, loaded: true};
    resolve({src: src, loaded: true});
  }
 });
 }
 }

और उपयोग

पहला इंजेक्शन

  constructor(
  private _script: ScriptLoaderService) {
  }

फिर

ngAfterViewInit()  {
this._script.loadScripts('app-wizard-wizard-3',
['assets/demo/default/custom/crud/wizard/wizard.js']);

}

या

    this._script.loadScripts('body', [
  'assets/vendors/base/vendors.bundle.js',
  'assets/demo/default/base/scripts.bundle.js'], true).then(() => {
  Helpers.setLoading(false);
  this.handleFormSwitch();
  this.handleSignInFormSubmit();
  this.handleSignUpFormSubmit();
  this.handleForgetPasswordFormSubmit();
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.