【问题标题】:Angular 2/4 loading scripts dynamicallyAngular 2/4 动态加载脚本
【发布时间】:2017-07-25 05:05:50
【问题描述】:

在 Angular 2 中,可以根据组件加载 CSS 样式。但是,没有相应的方法来加载脚本文件。我目前正在我的单页应用程序的基本页面上加载所有脚本,但这会导致优化问题。

为 Angular 2/4 组件加载脚本的建议方法是什么。

【问题讨论】:

  • 什么脚本?脚本不能与必须在 index.html 中的特定组件一起使用
  • 如果您需要加载第三方 JS 脚本或库,请尝试将其嵌入到您的应用程序中,而不是在 index.html 中使用它,这是link

标签: javascript angular angular2-routing


【解决方案1】:

您可以像这样在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 数组中。

【讨论】:

    【解决方案2】:

    您可以在任何组件中动态加载脚本。

    解决办法如下:

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

      // 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. 现在您只需要导入并调用服务。

      // 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)=>{
          });
      }
      

    它会动态添加'datatables'的脚本。

    这仅用于您的目的,但它只会在需要的地方加载。

    【讨论】:

    • 你有这个代码的工作 plnkr 吗?我试过了,我得到一个错误,它找不到 _script.load。
    • 没有 plnkr 但我知道了。看来你还没有在构造函数中定义脚本。这是示例-构造函数(public _script:Script){}这将解决您的错误。
    猜你喜欢
    • 1970-01-01
    • 2017-12-15
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 2017-02-16
    • 1970-01-01
    相关资源
    最近更新 更多