on
router-outlet에서 활성화된 컴포넌트 감지하기
router-outlet에서 활성화된 컴포넌트 감지하기
Angular 프로젝트를 진행할 때 동적으로 router를 사용하여 하위 페이지를 로드해야할 때가 많이 있는데요. 그럴 때 특정 페이지가 활성화 되었을 때 어떤 동작(scroll 을 맨 위로 올리다던가, 바탕색을 바꾼다거나 등)을 하고 싶다면 어떻게 해야 할까요?
이 때 사용할 수 있는 것이 바로 router-outlet의 activate 이벤트 입니다.
Angular 공식문서에 있는 RouterOutlet을 확인해 보시면 Properties 부분에 @Output으로 ‘activate’ 와 ‘deactivate’를 제공하고 있는 것을 확인할 수 있습니다.
Angular에서 제공하는 RouterOutlet의 ‘activate’ 와 ‘deactivate’ 이벤트를 활용하여 특정 페이지가 활성화 되었을 때만 pink 클래스를 적용하여 전체 글자색을 pink로 변경해보겠습니다.
먼저 아래의 명령어들로 테스트 프로젝트를 생성합니다. (실행 전에 Angular CLI를 먼저 설치해주세요)
ng new router-outlet cd router-outlet ng g module something1 && ng g c something1 ng g module something2 && ng g c something2 ng g module special && ng g c special
그리고 app-routing.module.ts 파일을 보시면 처음엔 아래와 같이 되어있을 것인데요.
// app-routing.module.ts import { NgModule } from ‘@angular/core’; import { Routes, RouterModule } from ‘@angular/router’; const routes: Routes = []; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
routes 배열에 우리가 추가한 모듈들을 자식 라우터로 추가해 줍니다.
// app-routing.module.ts import { NgModule } from ‘@angular/core’; import { Routes, RouterModule } from ‘@angular/router’; import { AppComponent } from ‘./app.component’; const routes: Routes = [ { path: ‘’, component: AppComponent, children: [ { path: ‘some1’, loadChildren: () => import(‘./something1/something1.module’).then((m) => m.Something1Module), }, { path: ‘some2’, loadChildren: () => import(‘./something2/something2.module’).then((m) => m.Something2Module), }, { path: ‘special’, loadChildren: () => import(‘./special/special.module’).then((m) => m.SpecialModule), }, ], }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], }) export class AppRoutingModule {}
이제 각 모듈들에도 routes를 추가해주어야 합니다. 아래와 같이 각 모듈들에 추가해 주시면 됩니다.
// something1.module.ts import { NgModule } from ‘@angular/core’; import { CommonModule } from ‘@angular/common’; import { RouterModule, Routes } from ‘@angular/router’; import { Something1Component } from ‘./something1.component’; const routes: Routes = [ { path:’’, component: Something1Component } ]; @NgModule({ declarations: [Something1Component], imports: [ CommonModule, RouterModule.forChild(routes) ] }) export class Something1Module { }
이제 app.component.html 과 app.component.ts 파일 내에서 router-outlet의 activate 이벤트를 감지하여 로그를 찍어보겠습니다.
// app.component.html // app.component.scss .pink { color: pink; } // app.component.ts import { Component } from ‘@angular/core’; @Component({ selector: ‘app-root’, templateUrl: ‘./app.component.html’, styleUrls: [‘./app.component.scss’], }) export class AppComponent { title = ‘router-outlet’; onActivate(componentRef) { console.log(componentRef); } }
ng serve를 실행하여 localhost:4200을 브라우저로 접근해보시고 검사를 열어보시면 아래와 같이 로그가 찍히는 것을 확인하실 수 있습니다.
onActivate 로그
로그를 보시면 활성화된 컴포넌트에 소속되어있는 속성을 확인할 수 있는데요. 현재는 AppComponent가 로그에 찍혔기 때문에 title 속성에 접근할 수 있는 것을 확인할 수 있습니다.
그렇다면 이를 이용하여 특정 컴포넌트(여기서는 SpecialComponent)에만 속성을 추가하여 해당 속성(isPink)이 있을 때문 클래스를 적용하면 될 것입니다.
special.component.ts 파일에 isPink 속성을 추가하고 true 값을 지정해 줍니다.
// special.component.ts isPink: boolean = true;
app.component.ts 파일에도 isPink 속성을 추가해주고 로그만 찍던 onActivate 함수에는 componentRef에 isPink 속성이 있을 때만 isPink 값을 할당하도록 수정해줍니다.
// app.component.ts export class AppComponent { title = ‘router-outlet’; isPink: boolean = false; onActivate(componentRef) { this.isPink = componentRef?.isPink; } }
마지막으로 app.component.html에 ngClass를 이용하여 isPink가 true일 때만 pink 클래스가 적용될 수 있도록 코드를 수정해줍니다.
// app.component.html
이제 브라우저에서 locahost:4200/some1 과 localhost:4200/some2 에서는 똑같이 검정색 글씨로 나타나는 것을 확인할 수 있는데 반해
some1
some2
localhost:4200/special 로 접근했을 때는 글자가 분홍색으로 변하는 것을 확인할 수 있습니다.
special
이처럼 router-outlet을 사용할 때 activate 이벤트를 사용하면 필요한 페이지의 테마를 바꾼다던지 스크롤을 맨 위로 올린다던지와 같이 특정 동작을 특정 자식 페이지가 로드 되었을 때만 동작하는 것이 가능합니다.
from http://clap-yeon.tistory.com/76 by ccl(A) rewrite - 2021-11-29 15:01:36