меню

Не часто при разработке 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

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

HostListener и HostBinding

Использование декораторов HostListener и HostBinding для реагирования на события и работы со стилями в Angular

Инструкция по деплою Angular приложения на Github Pages

В данной инструкции мы разберём, как можно задеплоить Angular приложение на Github Pages на примере нового приложения.

Расширенные операторы RxJs, которые вы знаете, но недостаточно хорошо

Поскольку RxJS все еще остается важной частью Angular и обладает огромным количеством операторов, я решил написать эту статьи, чтобы выделить некоторые операторы, их комбинации и практические случаи использования, где они могут быть применены.

Binding свойств директив

Привязка входных и вторичных свойств директивы атрибута в Angular