이 게시물에는 코드작성이 포함되어 있습니다. 소스코드를 받으신 후 진행해 주세요. MEAN Stack/개발 환경 구축에서 설명된 프로그램들(git, npm, atom editor)이 있어야 아래의 명령어들을 실행할 수 있습니다.
이 게시물의 소스코드는 Tour of Heroes / Tour of Heroes - Hero 에디터 폼(form) (NgModel, Angular Pipe)에서 이어집니다.
tour-of-heroes.git 을 clone 한 적이 있는 경우: 터미널에서 해당 폴더로 이동 후 아래 명령어들을 붙여넣기합니다. 폴더 내 모든 코드가 이 게시물의 코드로 교체됩니다. 이를 원치 않으시면 이 방법을 선택하지 마세요.
tour-of-heroes.git 을 clone 한 적이 없는 경우: 터미널에서 코드를 다운 받을 폴더로 이동한 후 아래 명령어들을 붙여넣기하여 tour-of-heroes.git 을 clone 합니다.
- Github에서 소스코드 보기: https://github.com/a-mean-blogger/tour-of-heroes/tree/ee73104a7adb43088440f4155b62009b418c5f28
튜토리얼 사이트에 게시될 '영웅들'(heroes)의 목록을 mock data(임시로 사용하는 가짜 데이터) 배열로 만들고 이 영웅들의 목록을 웹사이트에 리스트로 나타내 봅시다.
mock-heroes.ts 파일은 ng generate
명령어로 만들 수 없고 직접 파일을 생성해야 합니다.
// src/app/mock-heroes.ts import { Hero } from './hero'; export const HEROES: Hero[] = [ { id: 11, name: 'Dr 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' } ];
이 사이트가 실전 사이트라면 당연히 DB를 연결하여 hero data를 저장하고 불러오겠지만, Tour of Heroes 튜토리얼의 목적은 Angular의 기초를 익히는 것이기 때문에 DB를 사용하지 않고 위와 같이 임시 데이터(mock data)를 만들어서 사용합니다.
const
키워드를 사용해서 HEROS
라는 상수(constant)를 선언합니다. 이 HEROES
상수의 타입은 Hero
class의 배열인 Hero[]
입니다. 이처럼 []
을 타입 뒤에 넣으면, '해당 타입의 배열' 타입을 타나냅니다.
이 상수 앞에 export
키워드를 붙여서 다른 파일에서 이 상수를 사용할 수 있게 하였습니다. 이전 강의에서는 Hero
class에 export
키워드를 붙였었는데요, 이처럼 어떠한 객체라도 export
키워드를 사용할 수 있으며, export
된 객체는 다른 파일에서 import
로 불러올 수 있습니다.
// src/app/heroes/heroes.component.ts import { Component, OnInit } from '@angular/core'; import { Hero } from '../hero'; import { HEROES } from '../mock-heroes'; // 1 ... export class HeroesComponent implements OnInit { heroes = HEROES; // 1 selectedHero: Hero; // 2 constructor() { } ngOnInit() { } onSelect(hero: Hero): void { // 3 this.selectedHero = hero; } }
이전 강의의 코드와 비교해서 변화가 없는 부분은 "..."로 생략하였습니다.
1. Heroes component에는 원래있던 hero
항목(property) 지우고 HEROES
상수를 가져와서 heroes
항목으로 추가하였습니다. hero
변수의 이름은 영어 단수형으로 hero 한명의 데이터를 담고 있었는데, 이제 배열인 HEROES
가 담기게 되니 heroes
라는 복수형이 되었습니다.
2. selectedHero
라는 항목도 추가되었는데, 이용자가 heroes
배열에서 하나의 hero
를 클릭하면, 클릭된 hero
가 selectedHero
에 담기게 됩니다. 이전 강의에서 만든 hero editor form 역시 이제 selectedHero
를 대상으로 작동합니다. 이 부분은 view 코드에서 자세히 살펴봅시다.
3. onSelect
함수는 view 코드에서 이용자가 영웅을 클릭하면 호출될 함수입니다. 처음으로 TypeScript의 함수를 만들었는데, 형태를 살펴봅시다.
TypeScript의 함수에는 :
를 사용해서 인자(parameter)에 타입을 줄 수 있고, 함수 자체에도 return 타입을 추가할 수 있습니다. onSelect
함수는 Hero
타입인 hero
인자를 하나 가지고 있고, 함수의 return 타입은 void
입니다. void는 함수가 어떠한 값도 return하지 않는다는 의미입니다. 함수의 인자 타입이나 함수의 return타입은 선택사항이며 이들을 제외해버리면 JavaScript의 함수와 100% 호환이 되는 형태입니다.
onSelect
함수는 hero인자를 selectdHero
에 대입하는 일을 합니다. onSelect
함수가 HeroesCompoent
class의 항목이고, selectdHero
역시 동일한 class의 항목이므로, onSelect
함수안에서 자신의 class의 selectdHero
항목에 접근하기 위해 this.selectedHero
를 사용했습니다. this
는 자기 자신 class의 항목을 사용할 때 항목 이름 앞에 붙이는 것을 알아 둡시다.
<!-- src/app/heroes/heroes.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 | uppercase}} Details</h2> <div><span>id: </span>{{selectedHero.id}}</div> <div> <label>name: <input [(ngModel)]="selectedHero.name" placeholder="name"/> </label> </div> </div>
1. *ngFor
를 사용해서 heroes
배열을 li 태그로 반복합니다. *ngFor는 *ngFor="let 반복에_사용될_변수명 of 배열"
의 형태로 사용합니다. heroes
배열 속의 데이터를 순서대로 하나씩 꺼내면서 해당 데이터를 hero
변수에 대입한 후 li 태그와 그 안의 코드들을 만들게 됩니다. 이때 li 태그 안의 코드에서는 hero
변수를 통해 heroes
배열의 해당 데이터를 사용할 수 있습니다.
2. [class.selected]="hero === selectedHero"
는 li 태그에 'selected'라는 css 클라스를 hero === selectedHero인 경우에만 추가하는 코드입니다. [class.클라스_이름]="조건"
의 형태로 css 클라스를 해당 태그에 dynamic하게 추가할 수 있습니다. 현재 *ngFor
통해 반복중인 hero
변수가 selectedHero
인 경우에만 'selected' 클라스를 li 태그에 추가합니다.
3. (click)="onSelect(hero)"
은 현재 해당 태그(현재 li 태그)에 click 이벤트가 오는 경우 onSelect
함수에 *ngFor
통해 반복중인 hero
변수를 인자로 넣어서 호출하는 코드입니다. 이처럼 (이벤트_이름)="함수_이름()"
를 사용해서 html 이벤트가 발생할 시 호출할 component의 함수를 지정할 수 있습니다. 사용할 수 있는 이벤트의 목록은 https://www.w3schools.com/jsref/dom_obj_event.asp 등 인터넷 검색을 통해 찾을 수 있습니다.
4. *ngIf
는 해당 태그(현재 div 태그)를 render할지 하지 않을지를 결정합니다. *ngIf="조건"
의 형태로 조건이 참인 경우에만 해당 태그를 render합니다. 현재 조건은 selectedHero
으로 selectedHero의 값이 존재하는 경우에만 이전강의에서 만든 hero editor form을 render합니다.
*ngIf
, *ngfor
와 같이 *
로 시작하는 명령어는 html 구조를 변경하는데 사용되는 명령어입니다.[태그_항목]
는 해당 태그_항목에 값을 전달할 때 쓰입니다.(이벤트)
는 해당 태그에서 발생하는 이벤트를 처리하기 위해 쓰입니다.[(ngModel)]
은 양방향으로 값을 주고 받으므로 ( )
와 [ ]
모두 쓰인 형태입니다.()
, []
, [()]
, *
다음에 오는 =""
안에는 typeScript 코드가 들어갑니다.사이트에 접속하면 위와 같이 mock data의 hero들이 나열되어 보여집니다. 하나를 클릭해 봅시다.
이전 강의에서 만들었던 hero editor가 밑에 나타나며 이전강의와 마찬가지로 작동합니다.
이번 강의에서는
:타입_or_클라스[]
this
*ngIf
*ngFor
[class.클라스_이름]
(이벤트)
( )
, [ ]
, [( )]
의 차이점에 대해 알아보았습니다. 위 개념들을 다른 사람에게 설명할 수 있을 정도로 이해할 수 있도록 합시다.
댓글
이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기