본문 바로가기

Web + APP/Angular

Angular : 같은 URL에서 Refetch data

반응형
SMALL

굉장히 직역 같은 제목입니다.

 

근데, 뭐 쉽게 말하자면, 같은 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();
  }
}

한 번 확인 해봅시다.

URL 변화도 없고, 잘 된다 !

어머나 세상에

 

너무 잘되네요 !

 

행복 !

 

근데 만약에요.

 

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

 

Angular: Refetch data on same URL navigation

Different approaches with their pros and cons

medium.com

 

여러분들은 똑똑하시니 알 수 있겠져


이상 Angualr : 같은 URL에서 Refetch data 였습니다 ^_^

반응형
LIST

'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