কৌণিকভাবে বাহ্যিক স্ক্রিপ্টগুলি কীভাবে লোড করবেন?


150

আমার এই মডিউলটি রয়েছে যা <script>সরাসরি সূচকগুলিতে ট্যাগটি যুক্ত না করে অতিরিক্ত যুক্তির সাথে বাইরের পাঠাগারকে একত্রিত করে :

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 {...}

আমি লক্ষ্য করেছি যে importES6 স্পাই দ্বারা স্থির এবং রানটাইমের পরিবর্তে টাইপস্ক্রিপ্ট ট্রান্সপ্লাইয়ের সময় সমাধান করা হয়েছে।

যাইহোক এটি কনফিগারযোগ্য করতে যাতে ফাইল.জগুলি সিডিএন বা স্থানীয় ফোল্ডার থেকে লোড হবে? স্ক্রিপ্টটি গতিময়ভাবে লোড করতে কৌণিক 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লোডারের ভবিষ্যত হওয়ায় এটি ঠিক আছে I
কল মেলএএনএন

6
TypeScript Plugin for Sublime TextSystemটাইপস্ক্রিপ্ট কোডটিতে খুশি হয় না : Cannot find name 'System'তবে স্থানান্তরিত এবং চলমান চলাকালীন কোনও ত্রুটি নেই। উভয় Angular2এবং Systemস্ক্রিপ্ট ফাইল ইতিমধ্যে যুক্ত করা হয়েছে index.html। যাই হোক করার এবং প্লাগইন খুশি করতে? importSystem
কল মেলএএনএন

1
তবে যদি আপনি system.js ব্যবহার না করেন!
মুরহফ সওসালি

2
@ ড্রুমুওর আমি মনে করি না কেন আমি কেন বলেছি, require()/ importআপনার উত্তর হিসাবে এখনই
ঠিকঠাক

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আপনার যেখানেই এটি প্রয়োজন সেখানে এটি ইনজেক্ট করুন এবং এর মতো জেএস লিবস লোড করুন

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

7
এটি দুর্দান্তভাবে কাজ করে। প্রাথমিক লোডের আকার 1MB এর চেয়ে বেশি শেভ করে - আমার অনেক লাইব্রেরি আছে!
আমাদের_বেনিফ্যাক্টররা

2
দেখে মনে হচ্ছে আমি খুব তাড়াতাড়ি কথা বলেছি। এই সমাধানটি আইওএস সাফারি তে কাজ করে না।
আমাদের_বেনিফ্যাক্টররা

স্ক্রিপ্টটি লোড করার পরে এটি আপনার ডোমের প্রধানের সাথে সংযোজন করা হচ্ছে কিনা তা পরীক্ষা করুন
রাহুল কুমার

সম্ভবত আমি সঠিকভাবে ইনজেকশন দিচ্ছি না তবে আমি পাচ্ছিthis.script.load is not a function
টাওলি

ধন্যবাদ। এটি কাজ করে তবে আমি আমার স্ক্রিপ্টটি (একটি পটভূমি অ্যানিমেশন) প্রতিটি অন্যান্য উপাদানগুলিতে লোড করছি। আমি এটি আমার প্রথম উপাদানটিতে লোড করা চাই (এটি একটি লগইন পৃষ্ঠা)। তা অর্জনে আমি কী করতে পারি? ধন্যবাদ
জোয়েল আজেভেদো

47

এটি কাজ করতে পারে। এই কোডটি গতিশীলভাবে বোতামে ক্লিক করা এইচটিএমএল ফাইলের <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
থ্যাঙ্কস ম্যান আমার জন্য কাজ করেছেন। আপনি এখন এটিকে পৃষ্ঠা লোডে Ngonit পদ্ধতি ব্যবহার করে লোড করতে পারেন। সুতরাং বোতাম ক্লিক প্রয়োজন হয় না।
নিরাজ

আমি একইভাবে ব্যবহার করছি .. তবে আমার পক্ষে কাজ হয়নি। আপনি কি দয়া করে এর জন্য আমাকে সাহায্য করতে পারেন ?? this.loadJs ("জাভাস্ক্রিপ্ট ফাইল"); সর্বজনীন লোডজ (ফাইল) {আসুন নোড = ডকুমেন্ট.ক্রেটএলমেন্ট ('স্ক্রিপ্ট'); node.src = ফাইল; node.type = 'পাঠ্য / জাভাস্ক্রিপ্ট'; node.async = সত্য; node.charset = 'utf-8'; document.getElementsByTagName ( 'মাথা') [0] .appendChild (নোড); }
মিতেশ শাহ

আপনি কি ক্লিক বা পৃষ্ঠার লোড এ তা করার চেষ্টা করছেন? আপনি আমাদের ফলাফল বা ত্রুটি সম্পর্কে আরও বলতে পারেন?
এনজি-ডারেন

হ্যালো, আমি এটি বাস্তবায়ন করার চেষ্টা করেছি এবং ঠিকঠাক কাজ করছি তবে new Promiseসমাধান হয়নি। আমাকে কি Promiseকিছু আমদানি করতে হবে?
ব্যবহারকারী 3145373

হাই, আমি যখন প্রতিশ্রুতি ব্যবহার করি তখন আমি বিশেষ কিছু আমদানি করি নি।
এনজি-ডারেন

23

আমি @ আরহুল কুমারদের উত্তরটি পরিবর্তন করেছি, যাতে এটি পরিবর্তে পর্যবেক্ষণগুলি ব্যবহার করে:

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 হ্যাঁ, আপনি যদি চান যে এটি সম্ভব। তবে আপনাকে এমন কিছু যুক্তি লিখতে হবে যা স্ক্রিপ্ট ট্যাগটি সরিয়ে দেয়। এখানে দেখুন: স্ট্যাকওভারফ্লো.com
জোয়েল

ধন্যবাদ জোয়েল, তবে স্ক্রিপ্ট দ্বারা আরম্ভ করা ফাংশনগুলি কোনওভাবে সরিয়ে দেওয়ার কোনও উপায় আছে? বর্তমানে আমি আমার কৌণিক 4 প্রকল্পে একটি সমস্যার মুখোমুখি হচ্ছি, কারণ ইম লোডিং স্ক্রিপ্ট যা জকিউই স্লাইডার সূচনা করে, তাই যখন প্রথম রুটটি এটি সঠিকভাবে প্রদর্শিত হয় তবে আমি যখন অন্য রুটে নেভিগেট করি এবং আমার রুটে ফিরে আসি তখন স্ক্রিপ্টটি দু'বার লোড হয় এবং স্লাইডার আর লোড হচ্ছে না :( আপনি আমাকে দয়া করে এই পরামর্শ দিতে পারেন
d123546

1
লাইনে একটি ত্রুটি রয়েছে private scripts: {ScriptModel}[] = [];। এটি হওয়া উচিতprivate scripts: ScriptModel[] = [];
ক্রিস হেইনেস

20

তবুও আরেকটি বিকল্প হ'ল সেই বিষয়ে scriptjsপ্যাকেজটি ব্যবহার করা

যে কোনও ইউআরএল থেকে অন-ডিমান্ডে আপনাকে স্ক্রিপ্ট সংস্থানগুলি লোড করতে দেয়

উদাহরণ

প্যাকেজ ইনস্টল করুন:

npm i scriptjs

এবং সংজ্ঞা টাইপ করুনscriptjs :

npm install --save @types/scriptjs

তারপরে আমদানি $script.get()পদ্ধতি:

import { get } from 'scriptjs';

এবং পরিশেষে স্ক্রিপ্ট সংস্থান লোড করুন, আমাদের ক্ষেত্রে গুগল ম্যাপস লাইব্রেরি:

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

ডেমো


ভাগ করে নেওয়ার জন্য ধন্যবাদ তবে কীভাবে ইউএসএল সহ অতিরিক্ত সম্পত্তি যুক্ত করতে পারে অ্যাসিঙ্ক ডিফার ?? উপরের লাইব্রেরি ব্যবহার করে কীভাবে এই স্ক্রিপ্টটি লোড করবেন আপনি আমাকে গাইড করতে পারেন? <স্ক্রিপ্ট টাইপ = 'পাঠ্য / জাভাস্ক্রিপ্ট' src = ' বিং .com /api/maps/mapcontrol?branch= re দয়া করে ' অ্যাসিঙ্ক স্থগিত> </script>
পুষ্কর রাঠোদ

যেহেতু সাবজেক্ট লাইন একই, আমি কেবল এখানে উত্তর প্রত্যাশা করছি
পুষ্কর রাঠোদ

দুর্দান্ত, তবে এনপিএম ইনস্টল - সেভ @ প্রকারের / স্ক্রিপ্টজগুলির পরিবর্তে এটি এনপিএম ইনস্টল হওয়া উচিত - সেভ-দেব @ টাইপ / স্ক্রিপ্টজ (অথবা ঠিক এনএমপি আই-ডি @ টাইপ / স্ক্রিপ্টজ)
ইউনেস হাডাস

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
এই ধরণের স্ক্রিপ্ট ইনজেকশনের সমস্যাটি হ'ল অ্যাংুলার যেহেতু এসপিএ, তাই আপনি স্ক্রিপ্টস ট্যাগটি ডিওএম থেকে অপসারণ করার পরেও এই স্ক্রিপ্টগুলি মূলত ব্রাউজার ক্যাশে থাকে।
j4rey

1
দুর্দান্ত উত্তর! আমার দিন বাঁচানো হয়েছে, এটি কৌনিক 6 এবং 7 এর সাথে কাজ করে!
নাদীশান হেরথ

বহিরাগত জেএসগুলিতে ডেটা প্রেরণ এবং বহিরাগত জেএস থেকে ডেটা পেতে, এই অ্যাপ্লিকেশনটিকে ডটকম অ্যাপ্লিকেশন.টায় কল করুন এবং var d3Sankey ডিক্লেয়ার ব্যবহার করুন: যে কোনও বৈশিষ্ট্য স্তরের মডিউলটির উপাদান হিসাবে। ইহা কাজ করছে.
gnganpath

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

স্ক্রিপ্টগুলি ডায়নামিকভাবে লোড করার আমার একটি ভাল উপায় আছে! এখন আমি আমার প্রকল্পে এনজি 6, ইচার্টস 4 (> 700 কেবি), এনজিএক্স-ইচার্ট 3 ব্যবহার করি। যখন আমি এগুলিকে এনজিএক্স-ইচার্টস ডক্স দ্বারা ব্যবহার করি, তখন আমার কৌণিক.জসন এচার্টগুলি আমদানি করা দরকার: "স্ক্রিপ্টস": ["./ নোড_মডিউলস / এচার্টস / ডিস্ট / এচার্টস.মিন.জেস"] এভাবে লগইন মডিউলে, স্ক্রিপ্টগুলি লোড করার সময় পৃষ্ঠাতে .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);
  }
}

তারপরে সাব-মডিউল-রাউটিং.মডিউল.টায় this এই প্রিলোডস্ক্রিপ্ট রিসোলভারটি আমদানি করুন:

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

এই কোডটি ভাল কাজ করে এবং এর প্রতিশ্রুতি দেয় যে: জেএস ফাইল লোড হওয়ার পরে, মডিউলটি লোড শুরু করবে! এই সমাধানকারীটি অনেক রাউটারে ব্যবহার করতে পারে


আপনি কি দয়া করে আইপিআরলোডস্ক্রিপ্টআরসাল্ট ইন্টারফেসের কোডটি ভাগ করে নিতে পারেন?
মেহুল ভাললা

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 বিন্যাস আমার typecript ফাইল কোথাও


যদি আমি একাধিক স্ক্রিপ্টগুলি foo, foo1, foo2 আমদানি করি এবং কেবলমাত্র কার্যকর করার সময় আমি জানি কীভাবে ঘোষণাটি গতিশীলভাবে করা যায়?
নটরায়ণ

2

আমার ক্ষেত্রে, আমি উপরের কৌশলটি ব্যবহার করে ফাইল jsএবং css visjsফাইল দুটিই লোড করেছি - যা দুর্দান্ত কাজ করে। আমি নতুন ফাংশন থেকে কলngOnInit()

দ্রষ্টব্য: এইচটিএমএল টেমপ্লেট ফাইলেকেবল একটিএবংট্যাগযুক্ত করেআমিএটি লোডকরতে পারিনি<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);    
}


আমি একটি বাহ্যিক ওয়েব উত্স থেকে সিএসএস ফাইল লোড করতে চাই। বর্তমানে "স্থানীয় সংস্থান লোড করার অনুমতি নেই" বলে আমি ত্রুটির মুখোমুখি হয়েছি .. দয়া করে পরামর্শ দিন।
করণ

আমি এইভাবে চেষ্টা করেছি। স্ক্রিপ্ট ফাইলগুলির জন্য এটি ভালভাবে কাজ করা সত্ত্বেও, এটি স্টাইলশিটগুলির পক্ষে কাজ করে না
118218

2

হাই, আপনি কোডের কয়েকটি লাইন দিয়ে রেন্ডারার 2 এবং এলিমেন্টের রেফ ব্যবহার করতে পারেন:

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 আমি একই সমস্যার মুখোমুখি হয়েছি এবং এনজিএফটারকন্টেন্টআইনিট (লাইফাইসাইকেল হুক) এর মতো উপাদানটিতে ব্যবহার করে এটি এখন কাজ করতে পেরেছি:

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

একটি নমুনা হতে পারে

স্ক্রিপ্ট-লোডার.সার্ভিস.সেট ফাইল

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();
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.