[Chapter 5] Angular 2 Tutorial - The Hero Editor 2
이번 챕터에서는 Hero Editor 의 Master / Detail Page 를 만들어 보겠습니다.
우선 Hero의 리스트를 늘려보겠습니다.
/src/app/app.component.ts 파일을 열어 수정합니다.
import { Component } from '@angular/core';
export class Hero {
id : number;
name : string;
}
const HEROES: Hero[] = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
];
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Tour of Heroes';
heroes = HEROES;
}
HEROES 라는 Hero 타입의 배열을 만들고 Hero 객체들을 넣었습니다.
그리고 로직에서는 heroes 라는 새로운 객체에 HEROES 를 대입하여 사용하도록 했습니다.
화면에서 나타날 수 있도록 /src/app/app.component.html 파일을 수정합니다.
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes">
<span class="badge">{{hero.id}}</span>{{hero.name}}
</li>
</ul>
app.component 의 로직코드에서 hero 라는 객체를 삭제하고 새로운 배열객체를 지정했기 때문에
기존 {{hero.id}} 와 {{hero.name}} 은 삭제하고
새롭게 지정한 heroes의 데이터를 나타내기 위해 *ngFor 라는 지시자를 사용했습니다.
*ngFor 는 해당 배열을 돌며 각 객체를 따로따로 담아서
변수에 저장하고 해당 템플릿에서 사용할 수 있게 만듭니다.
*ngFor = " 사용할 변수명 of 참조할 배열 " 으로 사용되며
여기서는 로직에서 지정해둔 heroes 배열을 참조해 hero 변수에 저장되도록 했습니다.
해당 변수를 이용하여 li 내부에서 {{hero.id}}, {{hero.name}} 을 사용하여 데이터를 보여줍니다.
서버를 켠 뒤 결과를 보겠습니다.
배열에 들어있는 영웅들의 목록이 li 태그에 들어와 나타납니다.
이제 스타일링을 위한 css 를 수정하도록 하겠습니다.
app.component.ts 의 stylesUrl 을 보면 app.component.css 파일을 스타일시트로 가르키고 있습니다.
/src/app/app.component.css 파일은 현재 비워져 있으므로 채워넣겠습니다.
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes .text {
position: relative;
top: -3px;
}
.heroes .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
저장 후 결과를 확인해보겠습니다.
정상적으로 적용된 것을 볼 수 있습니다.
다음으로 영웅을 클릭하면 상세한 정보가 나오도록 Event 를 넣겠습니다.
먼저 템플릿 파일에 click event 를 넣어야합니다.
/src/app/app.component.html 파일을 수정하겠습니다.
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes" (click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span>{{hero.name}}
</li>
</ul>
li 태그에 (click) = "onSelect(hero)" 라는 문구를 추가했습니다.
(click) 은 자바스크립트에서 쓰던 click 이벤트를 그대로 가져온 것 입니다.
내부적으로 해당 컴포넌트의 즉 현재는 app.component.ts 파일에서 정의한 onSelect 라는 이벤트를 실행시키며
Param으로 hero 변수를 설정했습니다.
여기서 hero 변수는 heroes 에서 가져온 hero 변수입니다.
onSelect 메소드를 만들어야 하는데 현재 하고자 하는 목적을 살펴보겠습니다.
영웅목록에서 영웅을 클릭하면 세부내용으로 해당영웅의 정보를 보여줘야 한다는 건
현재 선택된 영웅을 사용자가 목록에서 클릭한 영웅으로 바꿔줘야 한다는 것 입니다.
그러기 위해서 가장 먼저 필요한건 영웅을 지정할 변수가 있어야합니다.
그런 뒤 onSelect 에서 선택된 영웅의 데이터를 클릭한 영웅으로 바꿔주면 됩니다.
/src/app/app.component.ts 를 수정하겠습니다.
import { Component } from '@angular/core';
export class Hero {
id : number;
name : string;
}
const HEROES: Hero[] = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
];
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Tour of Heroes';
heroes = HEROES;
selectedHero: Hero;
onSelect(hero:Hero) : void {
this.selectedHero = hero;
}
}
selectedHero 라는 Hero 타입의 변수를 만들었고 여기에 현재 선택된 영웅의 데이터가 들어갑니다.
onSelect 메소드는 파라미터로 Hero 타입의 hero 를 받아서 selectedHero 의 데이터를 hero 로 변경합니다.
이벤트를 지정했으니 선택한 영웅목록을 보여주기 위한 디테일 화면을 만들어야합니다.
/src/app/app.component.html 파일을 수정합시다.
<h2>{{selectedHero.name}} details!</h2>
<div><label>id: </label>{{selectedHero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="selectedHero.name" placeholder="name"/>
</div>
디테일 화면에서는 로직에서 정의한 selectedHero 의 name, id 를 보여주고
양방향 데이터 바인딩을 사용하여 영웅의 이름을 바로 수정할 수 있도록 했습니다.
결과를 확인하겠습니다.
아무런 내용이 표시되지 않습니다.
크롬브라우저를 이용해 콘솔내용을 살펴보겠습니다.
에러 내용은 name 속성을 읽을 수 없다, 지정되지 않았다, name 속성이 필요하다 등의 오류가 있습니다.
selectedHero.name 이 문제가 생겼습니다.
현재 로직에서 selectedHero 에는 초기 데이터를 지정해 주지 않았기 때문에 읽을 수 없다는 에러가 납니다.
이 문제를 Angular 에서는 *ngIf 로 해결할 수 있습니다.
*ngIf 는 참인지 거짓인지, 데이터가 있는지 없는지 로 해당 부분을 표시하지 않도록 만듭니다.
/src/app/app.component.html 파일의 li 태그로 가서 *ngIf 를 넣어주겠습니다.
<div *ngIF="selectedHero">
<h2>{{selectedHero.name}} details!</h2>
<div><label>id: </label>{{selectedHero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="selectedHero.name" placeholder="name"/>
</div>
</div>
div 태그를 만들어 detail 에 관련된 부분을 감싸고 *ngIf 지시자를 사용했습니다.
대상은 selectedHero 입니다.
이제부터 Angular 는 해당 데이터가 없을 때 detail 부분을 DOM 밖으로 보내고
selectedHero 의 데이터가 생기면 해당 부분을 DOM 으로 가져와 표시합니다.
다시한번 확인해 보겠습니다.
영웅 목록도 정상적으로 출력되며 영웅의 이름도 정상적으로 수정되는 것을 볼 수 있습니다.
영웅을 선택했을 때 선택한 영웅은 목록에서 표시가 되도록 만들겠습니다.
영웅 목록에서 선택된 영웅의 배경색을 바꾸는 css 를 적용하면 되는데
이것을 위해 선택된 영웅의 class 를 추가하겠습니다.
그러기 위해서 템플릿 파일인 /src/app/app.component.html 파일을 수정하겠습니다.
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)"
>
<span class="badge">{{hero.id}}</span>{{hero.name}}
</li>
</ul>
<div *ngIF="selectedHero">
<h2>{{selectedHero.name}} details!</h2>
<div><label>id: </label>{{selectedHero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="selectedHero.name" placeholder="name"/>
</div>
</div>
li 태그에 [class.selectedd]="hero === selectedHero" 라는 코드를 추가했습니다.
[] 는 단방향 데이터 바인딩으로 Angular 에서는 속성값을 조작할 때 쓰입니다.
그리고 class.selected 는 class="selected" 를 추가한다는 뜻입니다.
코드를 해석해보면 li 태그의 class="selected" 라는 속성을 추가하는데
hero 객체가 selectedHero 와 같은 것만 추가하고 나머지는 제거한다 라는 뜻입니다.
selected 는 이미 css 파일에서 정의를 해뒀기 때문에 해당 데이터는 selected 의 css 를 적용받습니다.
적용 후 css 가 제대로 적용되는 것을 확인했습니다.
요소를 확인해 보면 class="selected" 가 추가 된 것도 확인가능합니다.
이번 챕터는 내용이 좀 길었던 것 같습니다...
REFERENCE
http://alexband.tistory.com/
'Javascript > Angular' 카테고리의 다른 글
[Chapter 7] Angular 2 Tutorial - The Hero editor 4 (1) | 2017.06.15 |
---|---|
[Chapter 6] Angular 2 Tutorial - The Hero editor 3 (0) | 2017.06.14 |
[Chapter 4] Angular 2 Tutorial - The Hero Editor 1 (3) | 2017.06.09 |
[Chapter 3] Angular 2 의 프로젝트 폴더구조 (0) | 2017.06.08 |
[Chapter 2] Angular 2 의 작동방식 (0) | 2017.06.02 |