Evento de redimensionamento de janela angular

Eu gostaria de realizar algumas tarefas com base no evento de redimensionamento da janela (no carregamento e dinamicamente).

Atualmente tenho o meu DOM da seguinte forma:

O evento triggers corretamente

 export class AppComponent { onResize(event) { console.log(event); } } 

Como faço para recuperar a largura e a altura deste object de evento?

Obrigado.

 
 onResize(event) { event.target.innerWidth; } 

ou

 @HostListener('window:resize', ['$event']) onResize(event) { event.target.innerWidth; } 

Os alvos globais suportados são window , document e body .

A resposta de @ Günter está correta. Eu só queria propor outro método.

Você também pode adicionar a binding do host dentro do @Component() . Você pode colocar o evento e a chamada de function desejada na propriedade host-metadata da seguinte forma:

 @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], host: { '(window:resize)': 'onResize($event)' } }) export class AppComponent{ onResize(event){ event.target.innerWidth; // window width } } 

A maneira correta de fazer isso é utilizar a class EventManager para vincular o evento. Isso permite que seu código funcione em plataformas alternativas, por exemplo, renderização no lado do servidor com Angular Universal.

 import { EventManager } from '@angular/platform-browser'; import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; import { Injectable } from '@angular/core'; @Injectable() export class ResizeService { get onResize$(): Observable { return this.resizeSubject.asObservable(); } private resizeSubject: Subject; constructor(private eventManager: EventManager) { this.resizeSubject = new Subject(); this.eventManager.addGlobalEventListener('window', 'resize', this.onResize.bind(this)); } private onResize(event: UIEvent) { this.resizeSubject.next(event.target); } } 

O uso em um componente é tão simples quanto adicionar este serviço como um provedor ao seu app.module e, em seguida, importá-lo no construtor de um componente.

 import { Component, OnInit } from '@angular/core'; @Component({ selector: 'my-component', template: ``, styles: [``] }) export class MyComponent implements OnInit { private resizeSubscription: Subscription; constructor(private resizeService: ResizeService) { } ngOnInit() { this.resizeSubscription = this.resizeService.onResize$ .subscribe(size => console.log(size)); } ngOnDestroy() { if (this.resizeSubscription) { this.resizeSubscription.unsubscribe(); } } } 

Aqui está uma maneira melhor de fazer isso. Baseado na resposta de Birowsky .

Etapa 1: crie um angular service com Observables RxJS.

 import { Injectable } from '@angular/core'; import { Observable, BehaviorSubject } from 'rxjs'; @Injectable() export class WindowService { height$: Observable; //create more Observables as and when needed for various properties hello: string = "Hello"; constructor() { let windowSize$ = new BehaviorSubject(getWindowSize()); this.height$ = (windowSize$.pluck('height') as Observable).distinctUntilChanged(); Observable.fromEvent(window, 'resize') .map(getWindowSize) .subscribe(windowSize$); } } function getWindowSize() { return { height: window.innerHeight //you can sense other parameters here }; }; 

Etapa 2: Injete o service acima e assine qualquer um dos Observables criados dentro do serviço onde quer que você queira receber o evento de redimensionamento da janela.

 import { Component } from '@angular/core'; //import service import { WindowService } from '../Services/window.service'; @Component({ selector: 'pm-app', templateUrl: './componentTemplates/app.component.html', providers: [WindowService] }) export class AppComponent { constructor(private windowService: WindowService) { //subscribe to the window resize event windowService.height$.subscribe((value:any) => { //Do whatever you want with the value. //You can also subscribe to other observables of the service }); } } 

Uma boa compreensão da Programação Reativa sempre ajudará na superação de problemas difíceis. Espero que isso ajude alguém.

Assumindo que <600px significa celular para você, você pode usar isso observável e inscrever-se nele:

Primeiro precisamos do tamanho atual da janela. Então criamos um observável que apenas emite um único valor: o tamanho atual da janela.

 initial$ = Observable.of(window.innerWidth > 599 ? false : true); 

Então precisamos criar outro observável, para sabermos quando o tamanho da janela foi alterado. Para isso, podemos usar o operador “fromEvent”. Para saber mais sobre os operadores do rxjs, visite: rxjs

 resize$ = Observable.fromEvent(window, 'resize').map((event: any) => { return event.target.innerWidth > 599 ? false : true; }); 

Mergulhe esses dois streams para receber o nosso observável:

 mobile$ = Observable.merge(this.resize$, this.initial$).distinctUntilChanged(); 

Agora você pode se inscrever assim:

 mobile$.subscribe((event) => { console.log(event); }); 

Lembre-se de desinscrever 🙂

Eu não vi ninguém falando sobre MediaMatcher de angular/cdk .

Você pode definir um MediaQuery e append um ouvinte a ele – então, em qualquer lugar no seu modelo (ou ts), você pode invocar coisas se o Matcher for correspondido. LiveExample

App.Component.ts

 import {Component, ChangeDetectorRef} from '@angular/core'; import {MediaMatcher} from '@angular/cdk/layout'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { mobileQuery: MediaQueryList; constructor(changeDetectorRef: ChangeDetectorRef, media: MediaMatcher) { this.mobileQuery = media.matchMedia('(max-width: 600px)'); this._mobileQueryListener = () => changeDetectorRef.detectChanges(); this.mobileQuery.addListener(this._mobileQueryListener); } private _mobileQueryListener: () => void; ngOnDestroy() { this.mobileQuery.removeListener(this._mobileQueryListener); } } 

App.Component.Html

 
I turn red on mobile mode

App.Component.css

 .text-red { color: red; } .text-blue { color: blue; } 

fonte: https://material.angular.io/components/sidenav/overview

Com base na solução de @cgatian, sugiro a seguinte simplificação:

 import { EventManager } from '@angular/platform-browser'; import { Injectable, EventEmitter } from '@angular/core'; @Injectable() export class ResizeService { public onResize$ = new EventEmitter<{ width: number; height: number; }>(); constructor(eventManager: EventManager) { eventManager.addGlobalEventListener('window', 'resize', e => this.onResize$.emit({ width: e.target.innerWidth, height: e.target.innerHeight })); } } 

Uso:

 import { Component } from '@angular/core'; import { ResizeService } from './resize-service'; @Component({ selector: 'my-component', template: `{{ rs.onResize$ | async | json }}` }) export class MyComponent { constructor(private rs: ResizeService) { } } 

No Angular2 (2.1.0) eu uso o ngZone para capturar o evento de mudança de canvas.

Dê uma olhada no exemplo:

 import { Component, NgZone } from '@angular/core';//import ngZone library ... //capture screen changed inside constructor constructor(private ngZone: NgZone) { window.onresize = (e) => { ngZone.run(() => { console.log(window.innerWidth); console.log(window.innerHeight); }); }; } 

Espero que esta ajuda!

Isso não é exatamente a resposta para a pergunta, mas pode ajudar alguém que precisa detectar mudanças de tamanho em qualquer elemento.

Eu criei uma biblioteca que adiciona events resized a qualquer elemento – Angular Resize Event .

Ele usa internamente ResizeSensor de consultas de elemento CSS .

Exemplo de uso

HTML

 

TypeScript

 @Component({...}) class MyComponent { width: number; height: number; onResized(event: ResizedEvent): void { this.width = event.newWidth; this.height = event.newHeight; } } 

Eu escrevi este lib para encontrar uma vez mudança de tamanho de limite de componente (resize) em Angular, isso pode ajudar outras pessoas. Você pode colocá-lo no componente raiz, fará o mesmo que resize a janela.

Etapa 1: importar o módulo

 import { BoundSensorModule } from 'angular-bound-sensor'; @NgModule({ (...) imports: [ BoundSensorModule, ], }) export class AppModule { } 

Etapa 2: adicione a diretiva como abaixo

Etapa 3: receba os detalhes do tamanho do limite

 import { HostListener } from '@angular/core'; @Component({ selector: 'simple-component' (...) }) class SimpleComponent { @HostListener('resize', ['$event']) onResize(event) { console.log(event.detail); } } 

Eu sei que isso foi perguntado há muito tempo, mas há uma maneira melhor de fazer isso agora! Eu não tenho certeza se alguém vai ver esta resposta embora. Obviamente, suas importações:

 import { fromEvent } from "rxjs/observable/fromEvent"; import { Observable } from "rxjs/Observable"; import { Subscription } from "rxjs/Subscription"; 

Então no seu componente:

 resizeObservable$: Observable resizeSubscription$: Subscription ngOnInit() { this.resizeObservable$ = fromEvent(window, 'resize') this.resizeSubscription$ = this.resizeObservable$.subscribe( evt => { console.log('event: ', evt) }) } 

Então não se esqueça de cancelar a inscrição no destroy!

 ngOnDestroy() { this.resizeSubscription$.unsubscribe() }