Angular Tutorial 2 — Components

Building Angular Component

John Cho
14 min readOct 5, 2020

지난 글:

Angular CLI를 이용하여 애플리케이션을 만들 최소한의 준비를 끝냈으니,
이번에는 Angular를 이용해 애플리케이션을 조금씩 만들어나가보도록 하겠습니다.

많은 웹 애플리케이션이 처음 하기에 좋은 튜토리얼로 Todo App을 많이 제공하는 데, 저는 Angular를 이용해서 운동을 기록하는 애플리케이션을 만들어보겠습니다.

지금 당장 이해가 되지 않는 항목이 있더라도, 처음부터 순서대로 따라하면서 진행해보도록 하겠습니다.

이 챕터의 목표

  1. Angular 작업 환경을 이해합니다.
  2. 운동을 나타내는 Workouts 컴포넌트를 제작합니다.

Angular 작업 환경

Angular CLI를 이용해서 처음 개발 환경을 세팅하고 나면 여러분들이 혼란스러워 할 거라 생각합니다. 그도 그럴 게 꽤 많은 파일이 한번에 생성되었는 데, 어느 파일을 어떻게 수정해야할 지 이해하기 어려울거라 생각되기 때문입니다.

하지만 여러분들이 실제로 개발해나가는 과정에서 제일 중요한 폴더는 src 폴더로, 다른 파일과 폴더들은 차차 이해해나가도 충분합니다. 다만 여기서 간략하게 전체 폴더와 파일 구조에 대해서 설명하고 넘어가겠습니다.

.firebase/         * 파이어베이스 폴더
dist/ * 빌드 결과물을 나타내는 폴더
e2e/ * E2E 테스트를 위한 파일을 보유하고 있는 폴더
node_modules/ * 웹 애플리케이션이 의존성을 지닌 Node Module 폴더
src/ * 웹 애플리케이션 구동을 위한 실제 소스코드
.browserslistrc * 지원 브라우저 범위를 나타내는 파일
.editorconfig * 에디터 설정 파일
.firebaserc * 파이어베이스 설정 파일
.gitignore * git 버전 관리 제외 설정 파일
angular.json * Angular 설정 파일
firebase.json * firebase 설정 파일
karma.conf.js * karma (테스트 도구) 설정 파일
package.json * 웹 애플리케이션에 대한 전반적인 설정
README.md * 웹 애플리케이션 소개 문서
tsconfig.json * 타입스크립트 설정
tsconfig.app.json * 앱 타입 설정 (타입스크립트)
tsconfig.spec.json * 테스트 타입 설정 (타입스크립트)

Angular로 개발하는 게 아니더라도 추후에 TypeScript로 개발을 하게되면 tsconfig 파일에 대해서 이해가 필요할 거라 생각됩니다. 웹 애플리케이션 구축 전반적으로 package.jsonnode_module가 어떤 역할을 하는 지에 대해서는 이해하시면 좋습니다.

이번에는 src 폴더 내부를 살펴보겠습니다. 여러분들이 가장 많이 수정하게 될 폴더이며, 아마 크게 무리가 없다면 대부분의 경우에는 이 폴더 내부만 수정하게 될 것입니다.

src/
- app/ * 웹 애플리케이션의 로직과 데이터를 정의하는 컴포넌트 폴더
- assets/ * 이미지, 비디오 등 Asset을 모아둔 폴더
- environments/ * 빌드 환경과 관련한 파일을 모아둔 폴더
- favicon.ico * 파비콘
- index.html * 웹 애플리케이션의 글로벌 HTML 템플릿
- main.ts * 웹 애플리케이션의 엔트리 포인트.
- polyfills.ts * 브라우저 지원을 위한 Polyfill 스크립트
- styles.css * 웹 애플리케이션의 전역 CSS
- test.ts * 유닛 테스트를 위한 엔트리 포인트.

여기 있는 파일들은 앞으로도 종종 수정하게 될텐데, 개 중에서도 app 폴더 내부가 자주 수정이 될 예정입니다. 그러니 아래에 이어지는 코드랩을 따라해보시면서 어떻게 파일이 수정되는 지 살펴보시길 바랍니다.

App 폴더 내부도 살펴보아야하는 데, 이 폴더에 대해서는 실제로 코드를 건드려보면서 다루어보도록 하겠습니다.

Angular Application

Angular에서 실제로 웹 애플리케이션 코드를 많이 가지고 있는 app 폴더 내부는 여러가지 파일로 이루어져 있습니다. 우선 여러분들이 현재 아무런 수정도 하지 않았다면 app 폴더 내부는 아래와 같은 구조를 가지고 있습니다.

app/
- app-routing.module.ts
- app.component.css
- app.component.html
- app.component.spec.ts
- app.component.ts
- app.module.ts

app-routing.module.ts 는 추후에 routing 개념을 다룰 때 설명할 예정이니 제외하도록 하고, 여기서는 Angular의 핵심 개념인 컴포넌트모듈을 설명하도록 하겠습니다.

Angular 애플리케이션의 구조

Angular 애플리케이션의 핵심 구조는 VIEW와 데이터 처리를 관장하는 Angular 컴포넌트와, 여러 Angular 컴포넌트를 묶는 ngModules를 핵심으로 두고 있습니다.

Angular CLI를 이용하는 경우라면 Angular 컴포넌트를 생성했을 때 CLI가 자동으로 app.module.ts 파일을 수정하여 ngModules에 컴포넌트를 묶어줍니다. 어떤 파일이 수정되는 지는 직접 살펴보시면서 진행하시길 바랍니다.

Angular 컴포넌트

Angular 컴포넌트는 뷰를 정의하며, 화면에 어떤 엘리먼트에 어떤 데이터를 표시할 지 지정합니다. 단순한 컴포넌트는 크게 3가지 파일로 구성되어 있습니다.

{}.component.html
{}.component.ts
{}.component.css
{}.component.spec.ts

여기서 HTML 파일과 CSS 파일은 VIEW 영역에서도 특히 화면에 보이는 템플릿 영역을 제어합니다. React를 다루어보셨던 분이라면 JSX에 익숙하실텐데, JSX가 별도 파일로 구분되어있다고 생각하시면 조금 더 이해가 편합니다.

{}.component.ts 는 해당 컴포넌트의 데이터와 데이터 제어, 그리고 컴포넌트의 메타데이터를 정의합니다. 따라서 데이터의 처리 및 데이터에 따른 렌더링 제어는 해당 파일에서 진행하게 됩니다.

{}.component.spec.ts 는 해당 컴포넌트의 유닛 테스트를 정의합니다. 해당 컴포넌트가 실제로 잘 동작하는 지 파악하는 가장 기본 단계로 테스트를 적용하는 것이 가능하며, 테스트 도입을 통해 논리 프로그래밍을 더 쉽게 할 수 있습니다.

Angular 컴포넌트 생성하기

당연히 여러분들이 파일을 일일히 추가하여 Angular 컴포넌트를 생성할 수도 있지만, 그렇게 작업하는 건 꽤 괴로운 일입니다. Angular는 cli에서 컴포넌트 생성을 바로 지원하기 때문에 해당 코드를 사용해보겠습니다.

앞서 이야기했던 것처럼 저희가 만들 애플리케이션은 운동 목록을 보여주고 수정할 수 있게 하는 애플리케이션입니다. 우선 workouts 라는 컴포넌트를 하나 생성해보겠습니다.

ng generate component workouts

그러면 CLI가 src/app/workouts 폴더를 생성하고, 해당 폴더 내부에 컴포넌트를 구성하는 파일 4가지를 제작합니다.

src/app/workouts
- workouts.component.css
- workouts.component.html
- workouts.component.spec.ts
- workouts.component.ts

개별 파일이 어떤 역할을 하는 지에 대해서는 앞서 설명했기 때문에, 먼저 저희가 만든 workouts 컴포넌트를 App에 노출시켜보도록 하겠습니다. Angular에서 자동으로 생성해준app.component.html 을 열고 코드를 수정해보겠습니다.

먼저 기존에 있던 코드는 cmd + a 로 모두 지워주도록 합니다. 그리고 나서 아래 코드를 입력합니다.

<h1>{{title}}</h1>
<app-workouts></app-workouts>

그리고 나서 터미널로 이동해 ng serve 를 하고난 후, localhost:4200 에서 결과물을 확인해봅시다.

APP 컴포넌트의 제목인 devfest와, Workouts 컴포넌트의 내용이 노출되고 있다.

그럼 이제 컴포넌트의 내부 구조를 더 살펴봅시다.

Angular 컴포넌트 파일

먼저 HTML 파일과 CSS 파일은 앞서 이야기한 것처럼 템플릿 파일로, 기본적인 HTML과 Angular에서 제공하는 템플릿 문법을 사용할 수 있으며, CSS는 말 그대로 CSS로 사용합니다.

예를 들어 앞서 봤던 파일의 템플릿은 이렇습니다:

workouts.component.html<p>workouts works!</p>

그렇다면 Component 정의 부분은 어떻게 구성되어 있을까요? Workouts 컴포넌트를 정의하는 파일인 workouts.component.ts 파일을 살펴보겠습니다.

import { Component, OnInit } from '@angular/core';// 컴포넌트의 정의 부분
@Component({
selector: 'app-workouts', // 컴포넌트의 CSS 요소 셀렉터
templateUrl: './workouts.component.html', // 컴포넌트의 템플릿 파일
styleUrls: ['./workouts.component.css'] // 컴포넌트의 스타일 파일
})

export class WorkoutsComponent implements OnInit {
constructor() { }
ngOnInit(): void { } // 라이프사이클 후킹 함수, 라이프사이클은 추후 설명
}

여기서 만약 데이터를 주입하여 노출시키고 싶다면 어떻게 해야할까요? 먼저 WorkoutsComponent 클래스에 workout 프로퍼티를 추가하겠습니다.

export class WorkoutsComponent implements OnInit {
workout = "데드리프트"
constructor() { }
ngOnInit(): void { } // 라이프사이클 후킹 함수, 라이프사이클은 추후 설명
}

그리고 나서 HTML 템플릿을 수정해주면 됩니다.

<p>{{workout}}</p>
클래스에서 정의한 데이터가 삽입된다.

타입스크립트 인터페이스 생성하기

Angular는 기본적으로 타입스크립트를 기반으로 하고있기 때문에, 타입스크립트의 장점을 살리면서 Angular 코딩을 하는 것이 더 유용합니다.

인터페이스는 클래스, 변수, 함수에서 데이터의 타입 체크를 위해서 사용하며, 자바스크립트는 기본적으로 동적 언어이기 때문에 인터페이스를 지원하지 않지만 타입스크립트에서는 인터페이스를 지원합니다.

Workout 인터페이스를 생성하고, Workout 객체가 표현하는 데이터에 대해서 정의합니다. 인터페이스는 src/app/ 폴더에서 선언해주도록 하겠습니다.

src/app/Workout.tsexport interface Workout {
id: number;
name: string;
count: number;
}

대부분의 객체가 고유값을 가지기 때문에 고유값을 표시하기 위한 id와 운동 이름을 나타내는 name, 그리고 횟수를 나타내줄 count를 지정했습니다.

이렇게 인터페이스를 생성하고 나면, WorkoutsComponent 클래스에서 인터페이스를 선언하면 됩니다.

import { Component, OnInit } from '@angular/core';
import { Workout } from '../workout';
@Component({
selector: 'app-workouts',
templateUrl: './workouts.component.html',
styleUrls: ['./workouts.component.css']
})
export class WorkoutsComponent implements OnInit {
workout: Workout = {
id: 0,
name: "데드리프트",
count: 0
}
constructor() { }
ngOnInit(): void { }
}

인터페이스를 정의하면서 id, name, count의 기본값도 함께 정의해주었습니다. 데이터가 객체로 바뀌었으니, 템플릿에서 표시해주는 값도 객체로 바꾸어주겠습니다.

<article>
<h1>{{workout.name}}</h1>
<p>운동 횟수: {{workout.count}}</p>
</article>

이렇게 하고 나면 운동 횟수까지 노출시켜주는 컴포넌트를 만들 수 있습니다.

데이터 수정하기

Angular는 기본적으로 데이터의 양방향 바인딩 (Two-way Binding)을 지원하기 때문에 데이터를 여러 군데에서 수정하면서 동시에 데이터를 빠르게 갱신할 수 있습니다.

양방향 바인딩을 위해서는 Angular의 기본 모듈인 FormsModule 에서 제공하는 ngModel 디렉티브를 사용해야합니다.

먼저 app.module.ts 파일에서 FormModule을 로드하고, 앱 전체에서 사용할 수 있도록 imports 해오도록 하겠습니다.

import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { FormsModule } from '@angular/forms';import { AppRoutingModule } from './app-routing.module';import { AppComponent } from './app.component';import { WorkoutsComponent } from './workouts/workouts.component';@NgModule({  declarations: [    AppComponent,    WorkoutsComponent  ],  imports: [    BrowserModule,    AppRoutingModule,    FormsModule  ],  providers: [],  bootstrap: [AppComponent]})export class AppModule { }

이렇게 하면 개발 중인 Angular 애플리케이션에서 FormsModule이 포함되고, 이제ngModel 디렉티브를 사용할 수 있게 됩니다.

다시 WorkoutsComponent 템플릿으로 가서 수정을 위한 Input 을 만들어보겠습니다.

<article>
<h1>{{workout.name}}</h1>
<p>운동 횟수: {{workout.count}}</p>
<div>
<label>운동 횟수:
<input [(ngModel)]="workout.count"
type="number" placeholder="횟수">
</label>
</div>
</article>

추후에는 조금 더 이쁘게 꾸미겠지만 우선 이정도에서 마무리해보도록 하겠습니다.

정리

이번 글에서는 Angular의 작업 구조와 컴포넌트에 대해서 소개하였습니다.

당장은 아주 가벼운 애플리케이션이지만, 앞으로 만들어나가는 과정에서 더 많은 것들을 수행할 것이라 생각합니다. 이해가 안되는 내용이 있다면 댓글로 남겨주시면 추가하도록 하겠습니다.

YouTube:

--

--

John Cho
John Cho

No responses yet