쪼렙 as! 풀스택

17.09.28 Angular4 - Route 상태 저장해두기. RouteReuseStrategy 구현. 본문

개발 일지/Web & Server

17.09.28 Angular4 - Route 상태 저장해두기. RouteReuseStrategy 구현.

코코앱 2017. 9. 28. 17:36


https://thor3.fanzeel.com 을 작업하고 있다.


Angular 에서 '뒤로'버튼을 누르면 해당 컴포넌트가 첨부터 다시 Init 하면서, 첨부터 다시 렌더링을 한다.

필요한 데이터도 새로 불러오기 때문에, 모든 화면이 리프레시 된다.


내가 작업하고 있는 사이트에서는 메인페이지의 글 목록이 있는데, 예를 들어 "3"페이지에 있는 게시물을 선택해서 상세보기에 들어갔다가 다시 "뒤로"버튼을 눌러서 리스트 화면으로 돌아오면,

이게 컴포넌트를 처음부터 새로 생성하면서, 모든 데이터도 다시 불러오고 "1"페이지 부터 다시 보여지는 것이다. UI 상 큰 문제가 되었다.


이것을 해결하기 위해 Angular 에서 제공하는 RouteReuseStrategy 인터페이스를 구현해야 했다.



1. RouteReuseStrategy 를 implements 하는 CustomReuseStrategy 클래스를 만든다.


import {RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle} from "@angular/router";

export class CustomReuseStrategy implements RouteReuseStrategy {

handlers: {[key: string]: DetachedRouteHandle} = {};

//route 를 재사용할것인가. 어디서 어디로 옮길것인지 스냅샷이 넘어온다. 주소를 따져봐서, 같으면 재사용하고, 다르면 재사용하지 않는다.
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return this.getURL(curr) === this.getURL(future)
}

//Detach 될때 상태를 저장할건지 아닌지 리턴해준다. detach 되는 Route를 저장해 두려면 true, 저장하지 않으려면 false
shouldDetach(route: ActivatedRouteSnapshot): boolean {
//나는 URL이 루트인것만 저장해 둘것이기 때문에 루트인것만 true를 준다.
if(this.getURL(route) == "/"){
return true;
}else{
return false;
}
}

//위에서 저장하기로 한 스냅샷을 저장해둔다.

store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
let key = this.getURL(route);
this.handlers[key] = handle;
}

//저장해둔 Snapshot에 Attach 할 때의 델리게이트.
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!route.routeConfig && !!this.handlers[this.getURL(route)];
}

retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
if (!route.routeConfig) return null;
let key = this.getURL(route);
return this.handlers[key];
}


//routeSnapShot 에서 URL 을 계산해서 리턴해준다.
getURL(route: ActivatedRouteSnapshot) {
let next = route;
let url = "";
while(next) {
if (next.url) {
url = next.url.join('/');
}
next = next.firstChild;
}
url = "/" + url;
return url;
}
}



2. AppModule 에 provider 에 등록해주면 끝.

...
import {RouteReuseStrategy} from "@angular/router";
import {CustomReuseStrategy} from "./custom-reuse-strategy";

...

@NgModule({
declarations: [ ... ],
imports: [ ... ],
providers: [
...,
{provide: RouteReuseStrategy, useClass: CustomReuseStrategy}
],
bootstrap: [AppComponent]
})




나는 그냥 루트 상태만 저장해 두면 되기때문에, 간단하게 구현했지만,

path 간 이동할때마다 상태에 따라서, 굉장히 상세하게 설정할 수 있게 되어있다.



Comments