창 크기 조정 이벤트 (로드 및 동적)를 기반으로 일부 작업을 수행하고 싶습니다.
현재 다음과 같이 내 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('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 service
RxJS와 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
});
}
}
리 액티브 프로그래밍에 대한 올바른 이해는 어려운 문제를 극복하는 데 항상 도움이됩니다. 이것이 누군가를 돕기를 바랍니다.
답변
나는 대한 사람의 이야기를 보지 못했어요 MediaMatcher
의 angular/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); });
구독을 취소하십시오 🙂