source

Angular에서 동적으로 외부 스크립트를 로드하려면 어떻게 해야 합니까?

manysource 2022. 12. 13. 20:13

Angular에서 동적으로 외부 스크립트를 로드하려면 어떻게 해야 합니까?

이 모듈은 외부 라이브러리를 컴포넌트와 함께 추가 로직으로 구성하며,<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 {...}

나는 알아차렸다importby ES6 spec은 정적이며 실행 시가 아닌 TypeScript 전송 중에 해결됩니다.

CDN 또는 로컬폴더에서 file.js가 로딩되도록 설정 가능합니까?Angular 2에 스크립트를 동적으로 로드하도록 지시하려면 어떻게 해야 합니까?

다음 기술을 사용하여 필요에 따라 각도 프로젝트에서 JS 스크립트와 라이브러리를 동적으로 로드할 수 있습니다.

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필요한 곳에 jslibs를 이렇게 로드합니다.

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

system.js 를 사용하고 있는 경우는,System.import()실행 시:

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

Web 팩을 사용하고 있는 경우는, 로 강력한 코드 분할 서포트를 최대한으로 활용할 수 있습니다.

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

이거 먹힐지도 몰라.이 코드는 동적으로 부가됩니다.<script>에 꼬리표를 달다headhtml 파일의 on 버튼을 클릭합니다.

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

또 다른 선택지는 그 문제에 대한 패키지를 이용하는 것입니다.

임의의 URL에서 스크립트리소스를 온 디맨드로 로드할 수 있습니다.

패키지를 인스톨 합니다.

npm i scriptjs

정의를 입력합니다.

npm install --save @types/scriptjs

그럼 Import$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...
    });
  }
}

데모

@rahul kumars 응답을 수정하여 대신 Observatibles를 사용하도록 했습니다.

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
}

다음과 같이 여러 스크립트를 동적으로 로드할 수 있습니다.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어레이를 설정합니다.

안녕하세요 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()에서 호출해야 하는 경우에 매우 유용합니다.

이 코드 스니펫은 새로운 렌더러 API로 작성했습니다.

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

스택 블리츠

스크립트를 동적으로 로드할 수 있는 좋은 방법이 있습니다!현재 프로젝트에서 ng6, echarts4(>700Kb), ngx-echarts3를 사용하고 있습니다.ngx-echarts 문서에서 사용하는 경우 angular.json : "scripts" : [ . / node _ modules / echarts / dist / echarts . min . js ]에 에코차트를 Import해야 합니다.이거는 스크립트 로드 중 페이지입니다!나는 그것을 원하지 않아.

따라서 각 모듈을 파일로 각 로드하고 라우터 리졸버를 삽입하여 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);
  }
}

다음으로 submodule-routing.module.ts에서 이 PreloadScriptResolver를 Import합니다.

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

이 코드는 정상적으로 동작하며, js 파일이 로드된 후 모듈이 로드를 시작합니다! 이 해결 프로그램은 많은 라우터에서 사용할 수 있습니다.

Angular 범용 솔루션: 비디오를 재생하기 위해 스크립트를 로드하기 전에 특정 요소가 페이지에 표시될 때까지 기다려야 했습니다.

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

js ★★★★★★★★★★★★★★★★★」css visjs파일을 저장할 수 있습니다.합니다.ngOnInit()

주의: 단순히 추가만으로 로드할 수 없습니다.<script> ★★★★★★★★★★★★★★★★★」<link> file에 를 붙입니다.

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

역동적으로 스타일을 로드하고 싶은 분들을 위해(@Rahul Kumar의 훌륭한 답변에 근거합니다)

스크립트.스토어.ts

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

export const StyleStore: Scripts[] = [
    { name: 'fancybox-css', src: 'https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css' }
];

export const ScriptStore: Scripts[] = [
    { name: 'jquery', src: 'https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js' },
    { name: 'other', src: '[other script source]'}
];

스크립트 작성service.ts를 클릭합니다.

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

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

  private scripts: any = {};
  private styles: any = {};

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

    StyleStore.forEach((script: any) => {
      this.styles[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);
  }

  loadStyles(...scripts: string[]) {
    var promises: any[] = [];
    scripts.forEach((script) => promises.push(this.loadStyle(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') as any;
        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);
      }
    });
  }

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

}

app.component.ts

constructor(private scriptLoaderService: ScriptLoaderService) {
  this.scriptLoaderService.loadStyles('fancybox-css').then(x => {
    this.scriptLoaderService.load('jquery', 'fancybox').then(data => {
    }).catch(error => console.log(error));
  });
}

@rahul-supervar의 솔루션은 나에게 효과가 있지만, 나는 내 타이프스크립트에서 javascript 함수를 호출하고 싶었다.

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를 호출할 수 있어

아래 링크에도 같은 문제가 있었습니다.아주 쉽게 풀었어요.

https://www.gstatic.com/charts/loader.js

아래 코드의 구글 변수에 접속해야 했습니다.근데 앵글클래스에 넣었을 때는 안 되더라고요.

google.charts.load("current", {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
    var data = google.visualization.arrayToDataTable([
        ["Element", "Density", { role: "style" } ],
        ["Copper", 8.94, "dodgerblue"],
        ["Silver", 10.49, "dodgerblue"],
        ["Gold", 19.30, "dodgerblue"],
        ["Platinum", 21.45, "color: dodgerblue"]
    ]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
    { calc: "stringify",
        sourceColumn: 1,
        type: "string",
        role: "annotation" },
    2]);

var options = {
    title: "Density of Precious Metals, in g/cm^3",
    width: 600,
    height: 400,
    bar: {groupWidth: "50%"},
    legend: { position: "none" },
};
var chart = new google.visualization.ColumnChart(document.getElementById("columnchart_values"));
chart.draw(view, options);

}

ts 클래스 위에 동일한 이름(google)으로 글로벌 변수를 만들고 해당 변수를 자동으로 참조합니다(글로벌 범위이기 때문에).그러면 문제가 해결됩니다.

declare var google: any;

@d123546 같은 문제에 직면하여 ng After Content를 사용하여 현재 동작하고 있습니다.다음과 같이 컴포넌트 내의 Init(라이프 사이클 후크)를 실시합니다.

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)을 만듭니다.URLLoader

export class URLLoader {
  constructor() {

  }

  loadScripts() {

    const dynamicScripts = [
      'URL 1',
      'URL 2',
      'URL n'
    ];

    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('app-root')[0].appendChild(node);
    }
  }

}

) 2) URLLoader and을 불러주세요.loadScripts

export class AppComponent extends URLLoader implements OnInit {  

   constructor(){}

   ngOnInit() {
   super.loadScripts();
   }

}

깨끗하다고 수입해 주세요.ImportHttpClientJsonpModule 하는 거예요.

this.apiLoaded = this.httpClient.jsonp(environment.AnyApiUrl, 'callback')
  .pipe(
    map(() => true),
    catchError(() => of(false)),
  );

템플릿에서 다음을 수행합니다.

<app-component *ngIf="apiLoaded | async"></app-component>

이 솔루션은 여기 Angular Google Maps 공식 문서에 있습니다.

Angular는 사용자가 html 출력을 직접 간섭하지 않도록 하는 논리를 가지고 있습니다.그래서 당신은 Angular.json 파일에서 그 방향을 제시함으로써 Angular가 태그를 삽입하도록 해야 합니다.

먼저 스크립트 파일을 가져와야 합니다.두 가지 방법이 있습니다.

  1. 스크립트 파일 다운로드(somelibrary.js 등)
  • 자산 폴더에 저장
  • 스크립트의 상대 경로를 angular.json 파일의 "displicate" 섹션에 넣습니다.
"scripts": [
  "src/assets/somelibrary.js"
]
  1. npm/yarn을 사용하여 스크립트를 설치합니다.
  • 스크립트의 상대 경로를 angular.json 파일의 "displicate" 섹션에 넣습니다.
"scripts": [
  "./node_modules/somelibrary/dist/somelibrary.min.js"
]

샘플이 될 수 있다

스크립트 작성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();
});
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();
            }
        });
    }
}

Google 태그 관리자를 사용하여 코드를 입력하지 않고 외부 스크립트를 관리할 수 있습니다.이는 비기술 사용자 및 기술 사용자를 위한 완벽한 솔루션입니다.

언급URL : https://stackoverflow.com/questions/34489916/how-to-load-external-scripts-dynamically-in-angular