굉장히 직역 같은 제목입니다.
근데, 뭐 쉽게 말하자면, 같은 URL로 라우팅 됐을 때, 데이터를 다시 가져오는 방법을 알아보자 !
라고 이해하셔도 됩니다.
정말 성격 좋으시고, 일도 잘하시고, 개발자의 마음을 잘 헤아려 주시는 사랑스러우신 기획자 한 분이 계십니다.
이 분이 말하시길,
"같은 URL로 라우팅 됐을 때, 새로고침 시켜주실 수 없으실까요 ?"
(Angular는 같은 URL일 때, 아무 행동을 하지 않습니다 / 예시)
라고, 저에게 부탁을 주셨죠.
당연히, 제가 하는 일이 그런 일이기 때문에, 그리고 제가 존경하는 기획자 분이시기에 !
"암요 ! 가능합니다 !"
그대로 출동
막 뒤져봅니다.
오호, 생각보다 창의적인 생각이 많더라고요 ?
그 창의적인 생각을 한 번 알아봅시다.
1. TimeStamp queryParams를 이용하여 새로고침
this.router.navigate(['/routedComponent'], {
queryParams: {refresh: new Date().getTime()}
});
ngOnInit(): void {
this.activatedRoute.queryParamMap.subscribe((paramMap: ParamMap) => {
const refresh = paramMap.get('refresh');
if (refresh) {
fetchData();
}
});
}
timestamp는 흐릅니다.
거스를 수 없는 강물처럼요.
그렇기 때문에 이 변하는 값을 이용하여, 데이터를 새로 고쳐주는 방법입니다.
근데 요 방법, 문제가 있습니다.
URL이 너무 지저분 해지고요.
따로, 조치를 취하지 않으면, 뒤로가기 했을 때, 과거의 저희를 마주하게 됩니다. (/test => /test/refresh=100 => /test/refresh=110 =>(뒤로가기 클릭 !) /test/refresh=100 =>(뒤로가기 클릭 !) /test)
구질구질하죠 그죠 ?
그래서 다른 방법이 있습니다.
2. onSameUrlNavigation 속성 이용하기
Angular 5.1에 소개되는 onSameUrlNavigation property가 있습니다. 해당 property는 routers의 ExtraOptions으로 사용됩니다.
만약, current URL로 요청을 받았을 때, router가 무슨 일을 할 건지 정의하는 옵션입니다.
Default는 ignore입니답. (그래서 Angular는 아무 반응이 없었죠)
Angular 공홈에는 이렇게 말하네요.
그러면 요걸 이용해봅시다.
@NgModule({
imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
exports: [RouterModule],
})
export class AppRoutingModule {}
그리고 route changes를 감지하게 됐는데, 이를 구독하는 변수도 필요합니다.
아래처럼 구현할 수 있습니다.
import { Component } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { filter } from 'rxjs';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css'],
})
export class TestComponent {
time: number = 0;
private destroyed = new Subject<any>();
constructor(private router: Router) {
setInterval(() => (this.time += 1), 1000);
this.router.events
.pipe(filter((event) => event instanceof NavigationEnd), takeUntil(this.destroyed))
.subscribe(() => (this.time = 0));
}
ngOnDestroy(): void {
this.destroyed.next();
this.destroyed.complete();
}
}
한 번 확인 해봅시다.
어머나 세상에
너무 잘되네요 !
행복 !
근데 만약에요.
child component를 route를 하면 어떤 일이 생길까요?
const routes: Routes = [
{
path: 'test',
component: TestComponent,
children: [
{
path: 'detail',
component: DetailComponent,
},
],
},
];
이런 식으로요.
그러면, 나는 아들 Route로 이동했는데, 값이 새로고침 될 수도 있겠죠 ?
아래처럼요.
router가 event를 emit하고, 어찌됐건, 원치 않은 route가 동작할 수도 있겠죠.
이런 경우, nested된 route라고 볼 수 있는데, 이런 경우엔 parent route인지 child route인지 구분을 할 필요가 있습니다.
RxJS에서 pairwise operator가 존재하는데, 이전 NavigationEnd와 현재 NavigationEnd가 같은지 비교를 할 수 있습니다.
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css'],
})
export class TestComponent {
time: number = 0;
constructor(private router: Router) {
setInterval(() => (this.time += 1), 1000);
this.router.events
.pipe(
filter((event: RouterEvent) => event instanceof NavigationEnd),
pairwise(),
filter((events: RouterEvent[]) => events[0].url === events[1].url)
)
.subscribe(() => (this.time = 0));
}
}
요로코롬
성공 !
자 이제 이 방법을 이용해서, 기획자 분께서 부탁하신 일을 해결하러 가봅시다.
사실 이 이외에도, 많은 방법들이 있지만, 글쎄요. 저한텐 와닿지 않았습니다. (이해가 안되었다는 뜻 ㅎ)
https://medium.com/angular-in-depth/refresh-current-route-in-angular-512a19d58f6e
여러분들은 똑똑하시니 알 수 있겠져
이상 Angualr : 같은 URL에서 Refetch data 였습니다 ^_^
'Web + APP > Angular' 카테고리의 다른 글
NGRX - Reducers (0) | 2021.10.31 |
---|---|
NGRX - Actions (0) | 2021.10.24 |
Renderer2 in Angular 12 (Why not ElementRef ?) (0) | 2021.09.25 |
iOS 한글 buffer 문제 (1) | 2021.09.11 |
Angular Flex-Layout using MediaObserver (2) | 2021.08.28 |