Angular 적응형 웹(Adaptive Web) 구현
in Javascript
Angular에서 적응형 웹(Adaptive Web)을 구현하는 방법에 대해 알아보자. 아이디어는 간단하다. 초기에 브라우저 사이즈를 확인하고 각 사이즈에 따라 다른 컴포넌트를 보여주면 된다.
우선 모바일 여부를 관리할 ResolutionService
를 만들고 isMobileSubject
를 초기화한다. 그리고 EventManager
로 window 객체의 resize
이벤트를 등록해주고, resize
이벤트가 발생할때마다 isMobileSubject
를 변경해준다.
// resolution.service.ts
import { Injectable } from '@angular/core';
import { EventManager } from '@angular/platform-browser';
import { Observable, BehaviorSubject } from 'rxjs';
const MAX_MOBILE_WIDTH = 768;
@Injectable({
providedIn: 'root'
})
export class ResolutionService {
private isMobileSubject: BehaviorSubject<boolean>;
constructor(private eventManager: EventManager) {
this.isMobileSubject = new BehaviorSubject(this.windowRef.innerWidth < MAX_MOBILE_WIDTH);
this.eventManager.addGlobalEventListener('window', 'resize', this.onResize.bind(this));
}
get windowRef() {
return window;
}
get isMobile$(): Observable<boolean> {
return this.isMobileSubject.asObservable();
}
private onResize() {
this.isMobileSubject.next(this.windowRef.innerWidth < MAX_MOBILE_WIDTH);
}
}
위 서비스를 provider에 등록하고, 라우팅할 페이지의 root 컴포넌트에서 isMobile$
를 구독한다.
// main.component.ts
import { Component, OnDestroy } from '@angular/core';
import { ReplaySubject, Observable} from 'rxjs';
import { ResolutionService } from '@core/services/resolution.service';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-adaptive-main-page',
templateUrl: './main.component.html'
})
export class MainComponent implements OnDestroy {
isMobile$: Observable<boolean>;
private destroyed$: ReplaySubject<boolean> = new ReplaySubject(1);
constructor(private resolutionService: ResolutionService) {
this.isMobile$ = this.resolutionService.isMobile$.pipe(takeUntil(this.destroyed$));
}
ngOnDestroy() {
this.destroyed$.next(true);
this.destroyed$.complete();
}
}
템플릿에서는 isMobile$
에 따라 보여질 컴포넌트만 정의해주면 된다.
<!-- main.component.html -->
<ng-container *ngIf="(isMobile$|async); else desktop">
<h1 style="color: red">Mobile</h1>
</ng-container>
<ng-template #desktop>
<h1 style="color: blue">Desktop</h1>
</ng-template>
여기선 간단하게 작성했지만, main.mobile.component
, main.desktop.component
로 각각 컴포넌트를 만들면 관리하기 편하다. 위 코드는 Github에서 확인할 수 있다.