简体   繁体   English

Angular 2/4动态加载脚本

[英]Angular 2/4 loading scripts dynamically

In angular 2 one can load CSS styles depending on the component. 在angular 2中,可以根据组件加载CSS样式。 However, there is no corresponding way to load script files. 但是,没有相应的方式来加载脚本文件。 I am currently loading all scripts on the base page of my single page applications but that results in optimization issues. 我目前正在单页应用程序的基础页上加载所有脚本,但这会导致优化问题。

What is the advised way of loading scripts for an Angular 2/4 component. 建议为Angular 2/4组件加载脚本的方式是什么。

Well you can load script dynamically in any component. 好了,您可以在任何组件中动态加载脚本。

Here is the solution : 这是解决方案:

  1. Create a service in which you'll have js file. 创建一个包含js文件的服务。

     // 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. 现在创建一个将加载并返回脚本状态的服务。

     // 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 need to import & call the service. 现在,您只需要导入并调用服务即可。

     // import import {Script} from './script.service'; // specify the path where you have created the service // Now call service ngAfterViewInit() { this._script.load('datatables') .then((data:any )=>{ console.log(data,'script loaded') }) .catch((error)=>{ }); } 

It will dynamically add the script of 'datatables'. 它将动态添加“数据表”脚本。

This only serves your purpose but also it will load only where it is necessary. 这仅能满足您的目的,而且只会在必要时加载。

You can load multiple scripts dynamically like this in your component.ts file: 您可以在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);
    }
  }

and call this method inside the constructor, 并在构造函数中调用此方法,

constructor() {
    this.loadScripts();
}

Note : For more scripts to be loaded dynamically, add them to dynamicScripts array. 注意:要使更多脚本动态加载,请将它们添加到dynamicScripts数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM