Angular CodeLab 첫번째

이상훈
상훈 Devlog
Published in
13 min readOct 23, 2018

Angular 공식 홈페이지에서 제공하는 튜토리얼을 번역하고 정리한 글이다. 원문은 https://angular.io/docs에서 확인할 수 있다.

CodeLab 자료

보이지 않는다면 “SHOW EMBED”를 클릭!

순서

Angular Codelab 첫번째

  • 1. Introduction
  • 2. The Application Shell
  • 3. The Hero Editor
  • 4. Displaying a List
  • 5. Master/Detail Components

Angular Codelab 두번째

  • 6. Services
  • 7. Routing
  • 8. HTTP

1. Introduction

들어가기에 앞서

Hero 목록을 관리하는 Angular 어플리케이션을 제작한다. 이 어플리케이션은 Hero 목록을 전시하고 Hero 세부사항을 확인하며 그 정보를 편집하는 기능을 가진다.

튜토리얼이 끝나면 Angular 프레임워크를 통해 기본적인 엔터티 CRUD 관리 어플리케이션이 구현 가능할 것이다.

  • Angular 내장 Directive(*ngFor, *ngIf)를 통해 엘리먼트를 보여주거나 숨기며 히어로 목록을 전시
  • 히어로 목록을 보여주거나 히어로 상세 정보를 전시하는 Angular Component 생성
  • read-only 데이터를 위한 단방향 데이터 바인딩
  • 양방향 데이터 바인딩을 통한 편집 가능한 필드 추가
  • 키보드나 마우스 이벤트 등 사용자 이벤트를 컴포넌트 메소드와 바인딩
  • 사용자가 마스터 목록으로부터 히어로를 선택하고, 상세 뷰에서 히어로 정보 수정하기
  • Pipe를 통해 데이터 포맷을 바꾸기
  • 히어로 데이터를 Service를 통해 공유하기
  • 각각의 Component와 뷰들 사이를 라우팅하기

튜토리얼 수행 시 개발 환경은 다음과 같다.

  • NPM: 6.4.1
  • Node: 8.12.0
  • Angular CLI: 6.2.4
  • OS: macOS Sierra 10.12.6

구현 결과

구현 결과로는 크게 대시보드, 히어로 상세 정보, 그리고 히어로 전체 목록이 담긴 화면으로 이루어져있다.

전체 구조(대시보드, 목록, 상세 페이지)
예시 화면

2. The Application Shell

프로젝트 초기화

Angular 프로젝트를 개발하기 전, 가장 먼저 Angular CLI 설치한다.

npm install -g @angular/cli

설치한 Angular CLI를 통해 angular-tour-of-heroes 프로젝트를 생성한다.

ng new angular-tour-of-heroes

서버를 가동하여 초기화된 어플리케이션을 확인한다. http://localhost:4200/으로 접속한다.

cd angular-tour-of-heroes
ng serve --open

Angular Component 알아보기

Component는 Angular 어플리케이션의 가장 기본이 되는 구성 요소이다. 화면에 데이터를 표시하고 사용자로부터 입력 이벤트를 리스닝하고 반응한다.

title변수를 변경하면서 Component에 대해 자세히 알아본다. 프로젝트를 IDE에서 열고 src/app 폴더를 확인하면 다음과 같은 파일들이 있다.

  • app.component.ts: 타입스크립트로 작성된 컴포넌트 클래스 파일
  • app.component.html: HTML으로 작성된 컴포넌트 템플릿 파일
  • app.component.css: 컴포넌트의 CSS 스타일 파일(해당 컴포넌트만 가짐)
  • app.component.spec.ts: 컴포넌트 단위 시험을 위한 파일

app.component.ts의 title 멤버변수를 다음과 같이 수정한다.

app.component.html을 다음과 같이 수정한다. 이중 중괄호 표현은 Angular의 인터폴레이션 바인딩이다. 이것을 통해 Componenttitle 변수를 HTML에 전시하게 된다.

style.css을 다음과 같이 수정한다. 이 CSS 파일은 어플리케이션 전체의 스타일에 적용된다.

요약

  • Angular CLI를 통해 어플리케이션 초기화
  • Component의 데이터를 전시하는 방법
  • 제목을 전시하기 위한 인터폴레이션 바인딩(이중 중괄호)

3. The Hero Editor

히어로 컴포넌트 생성

Angular CLI를 통해 heroes Component를 생성한다.

ng gernerate component heroes

src/app/heroes 경로에 HeroesComponent의 세가지 파일이 생성된 것을 확인할 수 있다. 그 중 클래스 파일을 들여다 보자.

  • 컴포넌트에는 @Component 데코레이터를 가진 것을 볼 수 있다.
  • @ComponentComponent의 메타데이터를 명시하기 위한 함수이다.
  • selector: CSS 엘리먼트 요소 선택자를 의미한다.
  • templateUrl: 템플릿 파일 경로를 명시한다.
  • styleUrls: CSS 스타일 경로를 명시한다.
  • ngOnInit은 생명주기 훅 메소드, 컴포넌트가 생성된 후에 불려지며 주로 초기화를 위한 로직이 있는 곳이다.

hero 변수를 추가하고 전시

hero라는 변수를 다음과 같이 추가한다.

인터폴레이션 방법으로 앞서 선언한 hero를 전시한다.

HeroesComponent 뷰 전시

app-heroes라는 엘리먼트 선택자를 통해 AppComponent 템플릿 파일에 작성하여 HeroesComponent를 전시한다.

히어로 클래스 생성

단순한 string 타입의 히어로에서 좀 더 그럴듯한 히어로 객체를 만들어 보자.

히어로 객체 전시

앞서 선언한 hero 객체를 다음과 같이 전시한다.

Angular의 내장되어 있는 PipeUppercasePipe를 통해 hero 이름을 대문자로 표기할 수도 있다.

히어로 수정

<input> 텍스트 박스를 이용하여 히어로 정보 수정한다. 텍스트 박스는 히어로의 이름 속성을 표시하고 사용자가 입력 할 때 해당 속성을 업데이트한다. 즉, 컴포넌트 클래스에서 화면으로, 화면에서 클래스로 데이터 흐름을 처리하는 것이다.

[(ngModel)]은 Angular의 양방향 데이터 바인딩 문법이다. 텍스트 박스에 hero 이름을 입력하게 되면 hero 모델도 변경이 된다. 반대로 hero 모델이 변경되면 텍스트 박스의 값도 변경된다.

FormsModule 에러 발생

[(ngModel)]을 사용하면 다음과 같은 에러가 발생하게 된다. FormsModule을 제대로 import하지 않아서 생긴 문제이다.

Template parse errors:
Can't bind to 'ngModel' since it isn't a known property of 'input'.

모듈 등록

Angular는 메타데이터라고 불리는 프로그램에 필요한 파일이나 라이브러리 정보를 알아야 한다. 일부 메타데이터는 컴포넌트 클래스에 추가한 @Component가 있었다. 또 다른 중요한 메타데이터는 @NgModule 데코레이터에 있다. app.module.tsFormsModule을 추가한다.

HeroesComponent 선언

모든 컴포넌트는 반드시 NgModule에 선언이 되야 한다. 현재 app.module.ts를 보면 HeroesComponent가 이미 declarations에 추가되어 있는 것을 볼 수 있는데 이것은 우리가 Angular CLI를 통해 생성하였기 때문에 자동으로 등록 된 것이다.

요약

  • Angular CLI를 통해 HeroesComponent 생성
  • AppComponentHeroesComponent를 추가하고 전시
  • UppercasePipe를 통해 이름 포맷 변경
  • ngModel 지시자를 통해 양방향 데이터 바인딩
  • AppModule 학습
  • AppModuleFormsModuleimport하면 Angular가 ngModel 지시자를 인식하고 적용.

4. Display a Heroes List

이번에는 히어로가 하나가 아닌 여러 개를 전시해보고 한 히어로를 선택 시 상세 정보를 전시하는 기능을 추가해본다.

히어로 목록 전시

먼저 히어로 목업 데이터를 생성한다.

앞서 생성한 히어로 목록을 heroes 변수에 할당한다.

*ngFor를 통해 히어로 목록 전시한다. *ngFor는 Angular의 반복자 Directive이다. 이것은 목록의 각 요소에 대해 반복한다.

히어로 목록을 전시했으니 스타일을 다음과 같이 수정해본다.

Master/Detail

사용자가 Master에서 한 히어로를 클릭했을 때 Component는 선택된 히어로의 Detail을 페이지 하단에 전시할 것이다. 이번에는 클릭 이벤트를 리스닝하고 hero 상세 정보를 업데이트 해본다.

<li>에 클릭 이벤트를 바인딩하려면 다음과 같이 선언할 수 있다. 이것은 Angular의 이벤트 바인딩 문법이다. <li>가 클릭되었을 때 Angular는 onSelect(hero) 메소드를 실행한다.

선택된 hero 객체를 담을 selectedHero 변수와 이벤트 핸들러인 onSelect() 메소드를 작성한다.

상세 정보를 전시하기 위해 템플릿을 수정한다.

*ngIf를 통해 비어있는 데이터 숨기기

템플릿을 위와 같이 수정하면 다음과 같은 에러가 발생하게 된다. 히어로를 선택하지 않아 selectedHeroundefined이기 때문에 name 속성을 찾을 수 없어서 발생하는 에러이다.

HeroesComponent.html:3 ERROR TypeError: Cannot read property 'name' of undefined

이것을 해결하려면 Component에서는 히어로가 선택되었을 때(selectedHero가 할당이 되었을 때) 상세 정보를 전시해야 한다. 이때 <div>*ngIf Directive를 사용하여 selectedHerotrue일 때만 <div>를 DOM에 포함시키도록 한다.

선택된 히어로의 스타일 수정

다음과 같이 목록 중 선택된 히어로의 색을 강조하여 사용자가 어떤 히어로를 선택한 상태인지 알 수 있으면 좋을 것이다.

Magneta 히어로 선택 시

이것은 Angular의 클래스 바인딩을 통해 조건에 따라 CSS 클래스를 적용할지 제거할 지를 쉽게 구현할 수 있다. 문법은 다음과 같이 클래스 명에 적용할지 조건을 작성하면 된다.

*ngFor를 통해 heroes를 반복하며 요소를 생성할 때 hero가 selectedHero와 동일하다면 selected라는 클래스를 적용하게 된다.

요약

  • Master/Detail 뷰를 전시
  • 히어로를 선택하여 히어로 상세 정보를 볼 수 있음
  • *ngFor를 통해 데이터 목록 전시
  • *ngIf를 통해 HTML에 포함할지를 선택
  • 클래스 바인딩을 통해 CSS 스타일 토글

5. Master/Detail Component

HeroesComponent에서 히어로 목록과 선택된 히어로 상세 정보를 같이 전시하고 있다. 하나의 컴포넌트에 모든 기능을 담는 것은 어플리케이션이 커짐에 따라 유지보수를 하기 힘들다. 하나의 큰 컴포넌트를 작은 서브 컴포넌트들로 나눠야 할 것이다.

이번에는 히어로 상세 정보를 분리되고 재사용성이 가능한 HeroDetailComponent에 옮길 것이다. 그렇게 되면 HeroComponent는 오직 히어로 목록을 전시하는 기능만 담을 것이며, HeroDetailComponent는 선택된 히어로의 상세 정보만을 전시할 것이다.

HeroDetailComponent 구현

Angular CLI를 통해 hero-detail Component를 생성한다.

ng generate component hero-detail

앞서 설명한대로 Angular CLI를 통해 컴포넌트를 생성하면 다음과 같은 작업을 수행한다.

  • src/app/hero-detail 경로에 컴포넌트 파일들을 생성한다.
  • 컴포넌트 파일로는 hero-detail.component.css, hero-detail.component.html, hero-detail.component.ts, hero-detail.component.spec.ts가 생성된다.
  • app.module.ts에서 @NgModule 데코레이터에 HeroDetailComponent를 선언한다.

HeroesComponent의 템플릿 중 상세 정보를 전시하는 다음 부분을 잘라 HeroDetailComponent에 붙여넣는다. 또한 기존의 selectedHerohero로 변수명을 변경한다.

hero 변수에 @Input()을 추가하기

hero@Input() 데코레이터를 추가한다. 왜냐하면 외부의 HeroesComponent가 다음과 같이 hero를 바인딩을 할 것이기 때문이다.

<app-hero-detail [hero]="selectedHero"></app-hero-detail>

hero-detail.component.ts에서@angular/coreimport하고 @input 데코레이터를 추가한다.

이것이 HeroDetailComponent 클래스의 전부이다. 이 컴포넌트는 더이상의 변수도 필요없고 전시를 위한 로직도 필요 없다. 단순히 hero 객체를 받아 이것의 속성을 전시하는 것이 전부이다.

HeroesComponent 템플릿 수정하기

HeroDetailComponentselectorapp-hero-detail이다. 이것을 HeroesComponent 템플릿에서 히어로 상세 정보를 전시할 곳에 추가한다. 그 다음으로 HeroesComponentselectedHerohero 프로퍼티에 바인딩한다.

[hero]=”selectedHero” 이것이 Angular의 프로퍼티 바인딩이다. HeroesComponentselectedHeroHeroDetailComponenthero에 매핑하는 단방향 데이터 바인딩이다.

이제 사용자가 목록에서 히어로를 클릭하면 selectedHero가 변경되고 프로퍼티 바인딩을 통해 HeroDetailComponent에 선택된 히어로 정보를 전시한다.

전체 HeroesComponent 템플릿 코드는 다음과 같다.

요약

  • 분리되어 있고 재사용이 가능한 HeroDetailComponent를 생성하였다.
  • 프로퍼티 바인딩을 통해 부모 컴포넌트에서 자식 컴포넌트로 정보를 전달하였다.
  • @Input 데코레이터를 사용하여 hero를 외부 컴포넌트인 HeroesComponent가 바인딩할 수 있게 만들었다.

>> Angular CodeLab 두번째로 이동

--

--

이상훈
상훈 Devlog

Frontend Developer 😁😁 #angular #javascript #typescript #scala #node