[javascript] 각도 창 크기 조정 이벤트

창 크기 조정 이벤트 (로드 및 동적)를 기반으로 일부 작업을 수행하고 싶습니다.

현재 다음과 같이 내 DOM이 있습니다.

<div id="Harbour">
    <div id="Port" (window:resize)="onResize($event)" >
        <router-outlet></router-outlet>
    </div>
</div>

이벤트가 올바르게 시작됩니다

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

이 이벤트 객체에서 너비와 높이를 어떻게 검색합니까?

감사.



답변

<div (window:resize)="onResize($event)"
onResize(event) {
  event.target.innerWidth;
}

또는 HostListener 데코레이터 사용 :

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

지원되는 글로벌 목표는 window, document하고 body.

https://github.com/angular/angular/issues/13248 이 Angular로 구현 될 때까지 성능이 DOM 이벤트를 필수적으로 구독하고 RXJS를 사용하여 다른 답변 중 일부에 표시된 것처럼 이벤트 양을 줄이는 것이 좋습니다.


답변

@ 건터의 대답이 맞습니다. 방금 다른 방법을 제안하고 싶었습니다.

@Component()-decorator 내부에 호스트 바인딩을 추가 할 수도 있습니다 . 다음과 같이 이벤트 및 원하는 함수 호출을 host-metadata-property에 넣을 수 있습니다.

@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
   }
}


답변

나는 이것이 오래 전에 요청되었다는 것을 알고 있지만 지금이 더 좋은 방법이 있습니다! 그래도 누군가이 대답을 볼 수 있는지 확실하지 않습니다. 분명히 수입품 :

import { fromEvent, Observable, Subscription } from "rxjs";

그런 다음 구성 요소에서

resizeObservable$: Observable<Event>
resizeSubscription$: Subscription

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

그런 다음 파괴를 구독 취소하십시오!

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


답변

이를 수행하는 올바른 방법은 EventManager 클래스를 사용하여 이벤트를 바인딩하는 것입니다. 따라서 코드가 대체 플랫폼 (예 : 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<Window> {
    return this.resizeSubject.asObservable();
  }

  private resizeSubject: Subject<Window>;

  constructor(private eventManager: EventManager) {
    this.resizeSubject = new Subject();
    this.eventManager.addGlobalEventListener('window', 'resize', this.onResize.bind(this));
  }

  private onResize(event: UIEvent) {
    this.resizeSubject.next(<Window>event.target);
  }
}

구성 요소의 사용법은이 서비스를 app.module에 공급자로 추가 한 다음 구성 요소의 생성자에서 가져 오는 것만 큼 간단합니다.

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();
    }
  }
}


답변

여기에 더 좋은 방법이 있습니다. Birowsky의 답변을 기반으로 합니다.

1 단계 : 만들기 angular serviceRxJS와 Observables은 .

import { Injectable } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs';

@Injectable()
export class WindowService {
    height$: Observable<number>;
    //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<number>).distinctUntilChanged();

        Observable.fromEvent(window, 'resize')
            .map(getWindowSize)
            .subscribe(windowSize$);
    }

}

function getWindowSize() {
    return {
        height: window.innerHeight
        //you can sense other parameters here
    };
};

2 단계 : 위의 내용을 삽입 하고 창 크기 조정 이벤트를 수신하려는 모든 곳에서 서비스 내에 생성 된 항목 service을 구독 Observables하십시오.

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
        });
    }

}

리 액티브 프로그래밍에 대한 올바른 이해는 어려운 문제를 극복하는 데 항상 도움이됩니다. 이것이 누군가를 돕기를 바랍니다.


답변

나는 대한 사람의 이야기를 보지 못했어요 MediaMatcherangular/cdk.

MediaQuery를 정의하고 리스너를 첨부 할 수 있습니다. 그런 다음 Matcher가 일치하는 경우 템플리트 (또는 ts)의 어느 곳에서나 컨텐츠를 호출 할 수 있습니다.
라이브 예

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

<div [class]="mobileQuery.matches ? 'text-red' : 'text-blue'"> I turn red on mobile mode
</div>

App.Component.css

.text-red {
   color: red;
}

.text-blue {
   color: blue;
}

출처 : https://material.angular.io/components/sidenav/overview


답변

<600px가 사용자에게 모바일을 의미한다고 가정하면이 관찰 가능 항목을 사용하여 구독 할 수 있습니다.

먼저 현재 창 크기가 필요합니다. 따라서 현재 창 크기라는 단일 값만 방출하는 Observable을 만듭니다.

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

그런 다음 창 크기가 언제 변경되었는지 알 수 있도록 다른 관찰 가능 객체를 만들어야합니다. 이를 위해 “fromEvent”연산자를 사용할 수 있습니다. rxjs의 운영자에 대한 자세한 내용을 보려면 다음 사이트를 방문하십시오 : rxjs

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

이 두 개 스트림을 합병하여 관찰 가능한 것을 받으십시오.

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

이제 다음과 같이 구독 할 수 있습니다.

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

구독을 취소하십시오 🙂