Динамическое добавление элемента script в Angular
Не часто при разработке 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
Лучшая практика проектирования больших Angular-приложений
Интеграция Keycloak - Angular: Практическое руководство по подключению приложения к системе управления идентификацией и доступом (IAM)
Расширенные операторы RxJs, которые вы знаете, но недостаточно хорошо
Angular Signals — использование функции untracked() для предотвращения отслеживания зависимостей
Установка Playwright в сочетании с TypeScript для приложений Angular
Angular Routing в Angular 17
Обнаружение локальных изменений в Angular 17
Появление нового функционала в Angular 16 и Angular 17
15 Angular директив на каждый день
Улучшение читаемости кода в проектах Angular: мастерство работы с Enum и лучшие практики
Изменяют ли автономные компоненты способ написания кода в Angular?
Angular Signals
От хорошего к великому: параметры входных данных, inputs в Angular
Angular Interceptor - перехватчик ошибок http
10 лучших UI библиотек для Angular
Инструкция по деплою Angular приложения на Github Pages
Что ждет нас в Angular 15?
Angular Swiper Image Touch Slider
Angular Interceptors - рабочий пример
Динамическое добавление элемента script в Angular
Создание custom form field control (ControlValueAccessor)
Angular тестирование component с помощью Jest
Route Resolving
Шпаргалка по Angular
Директивы ng-template, ngTemplateOutlet и ng-container
Маршрутизация Angular подробное руководство
Angular & Rxjs: Отписываться или не отписываться?
Кастомные элементы форм в Angular
Формы. Реактивный подход.
Формы. Шаблонный подход.
Формы в Angular
Subject
Observable. Subscribe и Unsubscribe
Route. Обновление шаблона
Route Resolving
Route передача статичных данных
Route. Контроль навигации с помощью сервиса
Route. Защита роутера
Route. Вынос настроек роутера
Route. Переключения и параметры
JavaScript операторы
Сервисы
Структурные директивы
Binding свойств директив
HostListener и HostBinding
Директива атрибута
Навигация. Передача данных событиями
События и жизненный цикл
ng-content
Инкапсуляция стилей и ссылки
Связывание свойств и событий
Компонент и модель
Директива ngFor
Angular CSS и Style
Динамические шаблоны в Angular
События
Компонент и данные
Шаблон и стили компонента
Создание компонентов в Angular
TypeScript, Bootstrap, Main.ts
Установка и первый запуск Angular
Руководство по Angular
Возможно, вам будет интересно
HostListener и HostBinding
Использование декораторов HostListener и HostBinding для реагирования на события и работы со стилями в Angular
Route Resolving
Разрешение данных это процесс их получения перед активацией роута. В приложении возможна задержка перед тем, как данные будут предоставлены сервером.
Шаблон и стили компонента
Стилилизация компонента в Angular, способы определения стилей, подключени внешнего файла стилей, вынесение кода шаблона во внешний файл html