ПРИХОДИТЕ УЧИТЬСЯ НОВОЙ ПРОФЕССИИ ЛЕТОМ СО СКИДКОЙ ДО 70%Забронировать скидку

Работа с событием изменения размера окна в Angular

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для эффективного отслеживания изменений размеров окна в Angular, используйте декоратор @HostListener:

typescript
Скопировать код
import { HostListener } from '@angular/core';

export class MyClass {
  @HostListener('window:resize', ['$event'])
  onResize(event) {
    // Реагируем на изменение размера окна
    console.log(`👀 Новая ширина окна: ${event.target.innerWidth}`);
  }
}

Этот подход позволяет управлять автоматическими подписками и грамотно отписываться в контексте жизненного цикла компонентов Angular.

Для оптимизации работы рекомендуем использовать RxJS:

typescript
Скопировать код
import { fromEvent, throttleTime } from 'rxjs';

const resizeObservable = fromEvent(window, 'resize').pipe(throttleTime(1000));
resizeObservable.subscribe(event => {
  console.log(`Ускоряемся: новая ширина окна ${event.target.innerWidth}`);
});

Этот подход улучшает производительность событий изменения размера окна и предотвращает возможные проблемы с производительностью приложения.

Пройдите тест и узнайте подходит ли вам сфера IT
Пройти тест

Углубление в обработку события изменения размера окна с использованием Angular и RxJS

Посмотрим на различные способы слежения за изменениями размера окна, используя возможности Angular и RxJS.

Снижение частоты срабатывания событий с помощью RxJS

Преобразуйте событие resize в Observable и используйте throttleTime для снижения частоты его вызова:

typescript
Скопировать код
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 отслеживает изменения размера окна, словно джедай, использующий Силу:

typescript
Скопировать код
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:

typescript
Скопировать код
@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(() => {}))
      )
    );
  }
}

Используйте этот сервис в компонентах для реагирования на изменения размера окна:

typescript
Скопировать код
@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 на сервере отсутствует:

typescript
Скопировать код
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 вы можете удобно управлять событиями изменения размера окна:

typescript
Скопировать код
import { EventManager } from '@angular/platform-browser';

constructor(private eventManager: EventManager) {}

ngOnInit() {
  this.eventManager.addGlobalEventListener('window', 'resize', this.onResize.bind(this));
}

onResize(event) {
  // Адаптируйтесь под изменения
}

Визуализация

Представьте ваше окно как красивый городской пейзаж, который необходимо корректировать при изменении его размеров:

Markdown
Скопировать код
Статичный вид: 🏙️☀️ (Чёткая картина начального размера окна)

Как только окно изменяет свой размер, происходит перенастройка:

Markdown
Скопировать код
🔧 Выполняем некоторые настройки...

Обработчик событий тут же адаптирует визуальное отображение:

JS
Скопировать код
window.addEventListener('resize', () => { /* 🏢🏫 Город мгновенно подстраивается */ });

А в результате мы получаем обновлённый вид:

Markdown
Скопировать код
После изменения размера: 🏙️🌥️ (Перекомпонованный вид, соответствующий новым размерам окна)

Профессиональные советы и предосторожности

Защита от утечки памяти

Не забудьте отписаться от событий в методе ngOnDestroy:

typescript
Скопировать код
ngOnDestroy() {
  this.resizeSubscription.unsubscribe(); // Предотвратите утечку ресурсов
}

Используйте привязки событий в шаблонах осторожно

Привязка (window:resize)="onResize($event)" может показаться удобной, но это не самый эффективный способ обработки событий.

Отслеживание проблем Angular

Вы должны быть в курсе известных проблем Angular, например, #13248, для более стабильной работы событий изменения размера окна.

Императивная обработка событий

Императивный подход может обеспечить более полный контроль над обработкой DOM-событий и часто ведет к улучшению производительности.

Полезные материалы