admin 모듈 생성
angular 1.x에서 모바일에서 퍼포먼스 문제가 나타나면서 angular 2.x에서 가장 크게 변한 부분이 모듈 부분이다. 모듈별로 개발하면 내가 원하는 모듈만 로딩되고 나머지 모듈은 lazy loading이 되면서 퍼포먼스를 개선할 수 있다. angular에서 모듈을 만드는 방법은 단순하다 @NgModule 데코레이터 하나만 붙이면 된다. angular 모듈은 자바스트립트 모듈과는 다른 개념이다. angular 에서 다른 모듈을 가져오는 방법은 imports 이고 모듈화 하는 방법은 exports 이다. 자바스크립트의 모듈과 구분하기 위해서 끝에 s가 붙어있다. 현재 사이트는 app 모듈 하나로만 구성이 되어있다. 모듈의 구성요소를 살펴보면 declarations 부분은 component, pipe, directive 는 반드시 여기 선언되어야 한다. 또한 반드시 하나의 모듈에만 선언되어야 한다. 한 component가 두개이상의 모듈에 선언할 수는 없다.
admin 모듈을 angular cli를 사용하여 만들어 보자.
1 |
ng g module admin |
admin 폴더가 만들어지고 그 안에 admin.module.ts가 생성되었다. @NgModule 데코레이터가 모듈을 만드는 역할을 하며 CommonModule이라는 외부 모듈을 하나 가져왔으며 아직 컴포넌트나, 파이프, 디렉티브는 없는 상태이다.
1 2 3 4 5 6 7 |
@NgModule({ imports: [ CommonModule ], declarations: [] }) export class AdminModule { } |
컴포넌트 생성
관리자 메뉴를 구성하는 컴포넌트인 index 컴포넌트를 생성한다. admin 모듈 아래에 생성되어야 하므로 위치에 주의해야 한다. 그리고 hero를 등록할수 있는 register-hero 컴포넌트와 hero를 관리하는 manage-hero 컴포넌트 3 개를 생성한다.
1 2 3 |
ng g component admin/index ng g component admin/register-hero ng g component admin/manage-hero |
라우팅 구성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
const routes: Routes = [ {path: '', component: IndexComponent, children: [ {path: '', component: DashboardComponent}, {path: 'register', component: RegisterHeroComponent}, {path: 'manage', component: ManageHeroComponent} ]} ]; @NgModule({ imports: [ CommonModule, RouterModule.forChild(routes) ], declarations: [IndexComponent, ManageHeroComponent, RegisterHeroComponent, DashboardComponent] }) export class AdminModule { } |
1 2 3 4 5 6 7 8 9 |
const routes: Routes = [ {path: '', component: HomeComponent}, {path: 'heroes', component: HeroesComponent, children: [ {path: 'detail/:hero_id', component: HeroDetailComponent} ]}, { path: 'admin', loadChildren: './admin/admin.module#AdminModule', }, ]; |
관리자 메뉴 구성
관리자 메뉴는 사이드 메뉴로 구성해보자
bootstrap의 list-group을 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 |
<div class="row"> <div class="col-sm-3"> <ul class="list-group"> <li class="list-group-item" routerLink="/admin/register">hero 등록</li> <li class="list-group-item" routerLink="/admin/manage">hero 관리</li> </ul> </div> <div class="col-sm-9"> <router-outlet></router-outlet> </div> </div> |
Index 컴포넌트가 관리자의 메뉴를 구성하고 children이 들어가는 부분에 router-outlet을 구성한다. 좌측 메뉴를 클릭하면 라우팅이 되는것을 볼 수 있다. 여기에 스타일을 입히자.
1 2 3 4 5 6 7 8 9 10 11 12 |
<div class="row"> <div class="col-sm-3"> <ul class="list-group"> <li class="list-group-item" routerLink="/admin/register" routerLinkActive="active">hero 등록</li> <li class="list-group-item" routerLink="/admin/manage" routerLinkActive="active">hero 관리</li> </ul> </div> <div class="col-sm-9"> <router-outlet></router-outlet> </div> </div> |
routerLinkActive 만 추가하면 해당 링크가 활성화가 되면 active 스타일이 적용되는것을 볼 수 있다.
상단 메뉴에 추가
상단메뉴에 추가할때 주의할 점이 있다.
아래와 같이 admin 메뉴를 누르게 되면 첫번째 메뉴인 hero 등록화면으로 이동한다.
여기서 하나의 문제점이 생기는데 무슨 문제점인지 먼저 찾아보자.
1 2 3 4 |
<li class="nav-item"> <span class="nav-link" routerLinkActive="selected" routerLink="/admin/register">admin</span> </li> |
찾았는가?
좌측메뉴 hero 등록메뉴에서 hero 관리 메뉴로 이동하면 상단 admin 메뉴가 active 처리가 안된다.
routerLinkActive는 현재 path를 포함한 패스에 대해서 active 클래스를 추가해주는데,
현재는 패스가 /admin/register로 되어있기 때문에 /admin/manage로 이동하게 되면 active 클래스를 추가해주지 못하는것이다.
수정방법
그러므로, 패스를 먼저 /admin으로 바꾸고, 라우팅 패스에는 리다이렉션 메뉴를 추가해줘야 한다.
1 2 3 4 |
<li class="nav-item"> <span class="nav-link" routerLinkActive="selected" routerLink="/admin">admin</span> </li> |
admin 모듈에 리다이렉션 패스를 추가한다.
1 2 3 4 5 6 7 |
const routes: Routes = [ {path: '', component: IndexComponent, children: [ {path: 'register', component: RegisterHeroComponent}, {path: 'manage', component: ManageHeroComponent}, {path: '', redirectTo: '/admin/register'} ]} ]; |