меню

Не часто при разработке SPA приложения появляется задача с динамическим добавлением JS файла на страницу.

В данной статье рассмотрим несколько возможных способов динамического добавления script в Angular.

Динамическое добавление css link и js script

Добавление link и script нативным способом в JavaScript

 
// Добавление стилей
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css';
document.head.appendChild(link);

// Добавление скрипта
const script = document.createElement('script');
script.src = 'https://code.jquery.com/jquery-3.3.1.slim.min.js';
document.body.appendChild(script)
  

Певрый способ

Примитивный способ. Аналогичен нативной вставке скрипта в тело документа, описанным чуть выше.

 
constructor(
  @Inject(DOCUMENT) private document: Document,
  private renderer2: Renderer2
) {}

ngOnInit(): void {
  const textScript = this.renderer2.createElement('script');
  textScript.src = 'https://code.jquery.com/jquery-3.3.1.slim.min.js';
  this.renderer2.appendChild(this.document.body, textScript);

  const srcScript = this.renderer2.createElement('script');
  srcScript.type = 'text/javascript';
  srcScript.text = `
    (function() {
      console.log('Hello from Siberia!')
    }());
  `;
  this.renderer2.appendChild(this.document.body, srcScript);
}
 

Второй способ

Более продвинутый способ: завернуть в Promise.

  
ngOnInit() {
  this.loadScript('https://code.jquery.com/jquery-3.3.1.slim.min.js').then(
    () => this.loadTextScript(`
        setTimeout(() => {
          $( "#promise-based" ).html( "PromiseBasedComponent..." )
        }, 2000);
    `)
  );
}

loadTextScript(text: string) {
  return new Promise(resolve => {
    const script = this.renderer2.createElement('script');
    script.text = text;
    this.renderer2.appendChild(this.document.body, script);
    resolve();
  });
}

loadScript(url: string) {
  return new Promise((resolve, reject) => {
    const script = this.renderer2.createElement('script');
    script.src = url;
    script.onload = resolve;
    script.onerror = reject;
    this.renderer2.appendChild(this.document.body, script);
  });
}
 

Трейти способ

Способ с использование ReplaySubject в сервисе:

  
import { Injectable, Inject } from '@angular/core';
import { ReplaySubject, Observable } from 'rxjs';
import { DOCUMENT } from '@angular/common';

@Injectable()
export class LazyLoadingScriptService {
    _loadedLibraries: { [url: string]: ReplaySubject<any> } = {};

    constructor(@Inject(DOCUMENT) private readonly document: any) { }

    loadScript(url: string): Observable<any> {
        if (this._loadedLibraries[url]) {
            return this._loadedLibraries[url].asObservable();
        }

        this._loadedLibraries[url] = new ReplaySubject();

        const script = this.document.createElement('script');
        script.type = 'text/javascript';
        script.src = url;
        script.onload = () => {
            this._loadedLibraries[url].next();
            this._loadedLibraries[url].complete();
        };

        this.document.body.appendChild(script);

        return this._loadedLibraries[url].asObservable();
    }
}

      
/* Usage */
this.lazyLoadService.loadScript('/assets/scripts/some-script.js').subscribe(() => {
   // code
});
 
Помощь сайту
ЮMoney:
4100 1180 7209 833
Карта Сбербанк:
2202 2080 6183 7127

Возможно, вам будет интересно

Route. Переключения и параметры

Работа с роутером и ссылками в Angular. Программное переключение роутера и параметры пути в Angular

10 лучших UI библиотек для Angular

Angular зарекомендовал себя, как один из самых популярных фреймворков JavaScript. Его компонентная архитектура позволяет разработчику разделить приложение на небольшие многократно используемые фрагменты.

TypeScript, Bootstrap, Main.ts

TypeScript - это суперсет, расширяющий возможности JavaScript наличием типов, классов, интерфейсов и т.д. Браузер не умеет выполнять TypeScript файлы, по этому их нужно компилировать в JS.

Route Resolving

Разрешение данных это процесс их получения перед активацией роута. В приложении возможна задержка перед тем, как данные будут предоставлены сервером.