Работа с событием изменения размера окна в Angular
Быстрый ответ
Для эффективного отслеживания изменений размеров окна в Angular, используйте декоратор @HostListener
:
import { HostListener } from '@angular/core';
export class MyClass {
@HostListener('window:resize', ['$event'])
onResize(event) {
// Реагируем на изменение размера окна
console.log(`👀 Новая ширина окна: ${event.target.innerWidth}`);
}
}
Этот подход позволяет управлять автоматическими подписками и грамотно отписываться в контексте жизненного цикла компонентов Angular.
Для оптимизации работы рекомендуем использовать RxJS:
import { fromEvent, throttleTime } from 'rxjs';
const resizeObservable = fromEvent(window, 'resize').pipe(throttleTime(1000));
resizeObservable.subscribe(event => {
console.log(`Ускоряемся: новая ширина окна ${event.target.innerWidth}`);
});
Этот подход улучшает производительность событий изменения размера окна и предотвращает возможные проблемы с производительностью приложения.
Углубление в обработку события изменения размера окна с использованием Angular и RxJS
Посмотрим на различные способы слежения за изменениями размера окна, используя возможности Angular и RxJS.
Снижение частоты срабатывания событий с помощью RxJS
Преобразуйте событие resize
в Observable
и используйте throttleTime
для снижения частоты его вызова:
import { fromEvent } from 'rxjs';
import { throttleTime } from 'rxjs/operators';
@Component({...})
export class MyClass implements OnInit, OnDestroy {
resizeObs;
ngOnInit() {
this.resizeObs = fromEvent(window, 'resize')
.pipe(throttleTime(500))
.subscribe(event => this.onResize(event));
}
onResize(event) {
// Реагируйте гибко, ведь так поступал бы Брюс Ли
}
ngOnDestroy() {
this.resizeObs.unsubscribe(); // Освободите ресурсы
}
}
Использование ViewportRuler из Angular CDK
ViewportRuler
отслеживает изменения размера окна, словно джедай, использующий Силу:
import { ViewportRuler } from '@angular/cdk/scrolling';
@Component({...})
export class MyClass implements OnInit, OnDestroy {
constructor(private viewportRuler: ViewportRuler) {}
ngOnInit() {
this.viewportRuler.change(500).subscribe(() => this.onViewportResize());
}
onViewportResize() {
// Выполните необходимые операции
}
ngOnDestroy() {
// И пусть Сила будет с вами!
}
}
Метод this.viewportRuler.change()
более мягко реагирует на изменения, обеспечивая при этом высокую производительность.
Централизация в Resize Service
Упростите архитектуру приложения, осуществляя управление через Resize Service:
@Injectable({ providedIn: 'root' })
export class ResizeService {
constructor(private ngZone: NgZone, private viewportRuler: ViewportRuler) {}
get onResize$() {
return this.ngZone.runOutsideAngular(() =>
this.viewportRuler.change().pipe(
throttleTime(500),
tap(() => this.ngZone.run(() => {}))
)
);
}
}
Используйте этот сервис в компонентах для реагирования на изменения размера окна:
@Component({...})
export class MyClass implements OnInit, OnDestroy {
constructor(private resizeService: ResizeService) {}
ngOnInit() {
this.resizeService.onResize$.subscribe(() => this.onResize());
}
onResize() {
// Подстраивайтесь под изменения
}
ngOnDestroy() {
// Не забывайте про очистку ресурсов после использования
}
}
Корректное взаимодействие с серверным рендерингом
Приспособление под SSR (Server-Side Rendering)
Не используйте прямое обращение к window
, когда речь идёт о серверном рендеринге, поскольку объект window
на сервере отсутствует:
import { PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
@Component({...})
export class MyClass implements OnInit {
constructor(@Inject(PLATFORM_ID) private platformId: Object) {}
ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
// Используйте API браузера разумно
}
}
}
EventManager от Angular
С EventManager
вы можете удобно управлять событиями изменения размера окна:
import { EventManager } from '@angular/platform-browser';
constructor(private eventManager: EventManager) {}
ngOnInit() {
this.eventManager.addGlobalEventListener('window', 'resize', this.onResize.bind(this));
}
onResize(event) {
// Адаптируйтесь под изменения
}
Визуализация
Представьте ваше окно как красивый городской пейзаж, который необходимо корректировать при изменении его размеров:
Статичный вид: 🏙️☀️ (Чёткая картина начального размера окна)
Как только окно изменяет свой размер, происходит перенастройка:
🔧 Выполняем некоторые настройки...
Обработчик событий тут же адаптирует визуальное отображение:
window.addEventListener('resize', () => { /* 🏢🏫 Город мгновенно подстраивается */ });
А в результате мы получаем обновлённый вид:
После изменения размера: 🏙️🌥️ (Перекомпонованный вид, соответствующий новым размерам окна)
Профессиональные советы и предосторожности
Защита от утечки памяти
Не забудьте отписаться от событий в методе ngOnDestroy
:
ngOnDestroy() {
this.resizeSubscription.unsubscribe(); // Предотвратите утечку ресурсов
}
Используйте привязки событий в шаблонах осторожно
Привязка (window:resize)="onResize($event)"
может показаться удобной, но это не самый эффективный способ обработки событий.
Отслеживание проблем Angular
Вы должны быть в курсе известных проблем Angular, например, #13248, для более стабильной работы событий изменения размера окна.
Императивная обработка событий
Императивный подход может обеспечить более полный контроль над обработкой DOM-событий и часто ведет к улучшению производительности.