My Profile Photo

DongChanS's blog


수학과 학생의 개발일지


Angular (4) Tutorial - 여러 객체들을 표현 + 디테일 페이지

위의 튜토리얼은 https://angular.io/tutorial 을 참고하였습니다.

1) Display a Heroes List

이전까지는 하나의 hero 객체만 표현했었는데,

이 컴포넌트를 이용해서 여러개의 hero 객체들을 표현하려면 어떻게 해야 할까요?

1-1. Create mock heroes

일단 여러개의 hero 데이터가 있어야 합니다.

일반적으로는 다량의 데이터를 데이터 서버(ex, firebase)를 통해서 가져올 것이나, 일단은 임시 데이터를 만들어서 사용해봅시다.

// mock-heroes.ts

import {Hero} from './hero';

export 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' }
];
  1. Hero 클래스를 임포트

  2. 임포트한 Hero 클래스를 이용한 배열을 만듬

    => 이 배열을 임포트해서 컴포넌트에서 사용해보자.

1-2. Displaying heroes

  1. 컴포넌트 ts 파일에서 Hero 객체의 배열들을 임포트하자.
  2. 임포트 한 뒤에 변수를 배열로 바꾸자.
  3. 배열의 원소들을 for문처럼 표현하기 위해 *ngFor directives를 이용하자.
import { Component, OnInit } from '@angular/core';
import { HEROES } from '../mock-heroes';

//생략..
export class HeroesComponent implements OnInit {
  heroes = HEROES;
    //생략...
}

<h2>히어로들</h2>
<ul>
  <li *ngFor="let hero of heroes">
    <div>이름 : {{hero.name}}</div>
    <div>번호 : {{hero.id}}</div>
  </li>
</ul>

*ngFor이라는 directive를 통해서 for문을 표현할 수 있습니다.

그러면, 각 li태그의 자식태그들은 hero라는 값을 사용할 수 있습니다.

참고로 *를 붙이는게 문법적으로 매우 중요하다고 하니 꼭 기억하도록 합시다.

6

1-3. Style the heroes

스타일링은 css파일을 통해서 하면 되는데,

특정 컴포넌트에 대한 디자인은 각각의 css파일에서 하는 것을 추천합니다.

그래야 재사용성을 높일 수 있기 때문입니다.

이런 각각의 css파일들을 잘 만들고 난 뒤에는,

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})

여기 보이는 styleUrls 배열을 통해서 파일을 적어주면 독립적으로 잘 사용할 수 있습니다.

2) Detail page

원하는 기능

  • 유저가 히어로들의 list를 클릭 => 각 히어로의 디테일을 표시

필요한 요소

  • 각 히어로 아이템을 클릭하는 이벤트를 감지
  • 히어로의 디테일 파일을 업데이트

2-1. Add a click event binding


<h2>히어로들</h2>
<ul>
  <li *ngFor="let hero of heroes" (click)="onSelect(hero)">
    <div>이름 : {{hero.name}}</div>
    <div>번호 : {{hero.id}}</div>
  </li>
</ul>

이벤트를 바인딩하는 것은 ( event 이름 )="함수" 와 같은 문법인데,

특정 이벤트를 실행하면 함수(method)를 실행한다는 뜻입니다.

앵귤러에서는 이 함수를 event handler라고 부릅니다.

아.. 그러고보니 타입스크립트에서 method는 어떻게 선언하나요? 알아보도록 합시다.

2-2. Add the click event handler

export class HeroesComponent implements OnInit {
  heroes = HEROES;
  selectedHero: Hero;
  onSelect(hero: Hero): void {
    this.selectedHero = hero;
  }
}

역시 typescript의 문법은 자바스크립트와 비슷한 점이 많습니다.

selectedHero: Hero는 마치 자바스크립트의 선언 문법과 비슷해보이구요.

onSelect(hero: Hero): void { this.selectedHero = hero; } 이부분은 오히려 자바의 메서드를 선언하는 부분과 비슷하네요.

아무튼 히어로를 클릭할 때 마다 this.selectedHero가 바뀌면서 그에 대한 정보를 표현해주는 것으로 보입니다.

2-3. Update the details template

그러면 이제 selectedHero를 이용해서 정보를 표현하는 태그들을 더 만들어봅시다.


<h2>{{selectedHero.name | uppercase}} Details</h2>
<div><span>id: </span>{{selectedHero.id}}</div>
<div>
  <label>name:
    <input [(ngModel)]="selectedHero.name" placeholder="name" />
  </label>
</div>

그런데..

7

요런 에러메시지가 뜨는데, 당연합니다. 처음에는 아무것도 클릭하지 않았으니

this.selectedHero는 undefined이고, 이녀석은 아무런 프로퍼티도 없으므로 name에 접근하면 큰 오류가 나는겁니다.

해결방법은 selectedHero가 없는 값이라면 아예 selectedHero를 사용하는 태그를 표시하지 않는 것입니다.

2-4. The fix - hide empty details with *ngif

ngif 조건문을 통해서 할 수 있습니다!

<div *ngIf="selectedHero">
	<!-- 아까 추가했던 내용 -->
</div>

8

정상적으로 잘 작동하며, 심지어 에러도 없습니다. 왜냐하면 조건문이 false일 때 DOM에서 아예 히어로 디테일을 제거하기 때문입니다. vue.js의 v-if 디렉티브와 동일합니다.

2-5. Style the selected Hero

angular는 style class binding을 vue에 비해서 쉽게 할 수 있습니다.

[class.(css 클래스 이름)] = "조건문"의 문법을 통해서 클래스를 추가할지 말지를 설정할 수 있는데요. 예를 들어,

[class.selected] = "selectedHero === hero" 라고 하면 hero객체와 selectedHero객체를 비교해서 값이 똑같다면 이 태그에 selected값이 생깁니다.

그것을 이용해서 css를 편집해봅시다.


<h2>히어로들</h2>
<ul>
  <li class="hero-list"
      *ngFor="let hero of heroes"
      [class.selected]="hero === selectedHero"
      (click)="onSelect(hero)">
    <div>이름 : {{hero.name}}</div>
    <div>번호 : {{hero.id}}</div>
  </li>
</ul>

.selected {
  border : 1px solid #181818;
}
comments powered by Disqus