본문 바로가기
옛날

Angular 튜토리얼 4

by 차가운게 조아 2020. 2. 24.

Github

폼(Forms)

데이터 다루기를 끝낸 시점에 온라인 쇼핑몰 앱에는 제품 목록 화면과 장바구니 화면이 존재합니다.

이번에는 폼으로 주문 기능을 추가해서 앱을 완성해 봅시다. 폼은 사용자의 정보를 입력받을 때 사용합니다.

Angular가 제공하는 폼

Angular 폼은 HTML이 제공하는 폼을 바탕으로 커스텀 폼 컨트롤을 정의하거나 Angular가 제공하는 유효성 검사 메커니즘을 활용합니다. Angular가 제공하는 폼 기능은 컴포넌트에 존재하는 객체를 기반으로 데이터를 처리하는 반응형 폼(Reactive form)과 템플릿만으로 처리하는 템플릿 기반 폼으로 구분할 수 있습니다.

폼 모델 정의하기

가장 먼저, 주문 정보를 저장할 폼 모델을 정의해야 합니다. 컴포넌트 클래스에 정의하는 폼 모델은 폼의 상태와 데이터를 저장하는 원천 데이터 역할을 합니다.

 

1. cart.component.ts 파일을 엽니다.

2. 폼 컨트롤은 Angular가 제공하는 FormBuilder 서비스를 사용하면 간단하게 만들 수 있습니다. 지금까지 사용했던 다른 서비스와 마찬가지로, FormBuilder를 사용하려면 이 서비스를 컴포넌트에 의존성으로 주입해야 합니다:

  • @angular/forms 패키지에서 FormBuilder 서비스를 로드합니다.

src/app/cart/cart.component.ts

import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';

import { CartService } from '../cart.service';

FormBuilder ReactiveFormsModule이 제공하는 서비스입니다. 이 모듈은 app.module.ts 파일에서 정의하는 AppModule에 이미 추가되어 있습니다.

  • FormBuilder 서비스를 의존성으로 주입합니다.

src/app/cart/cart.component.ts

export class CartComponent {
  items;

  constructor(
    private cartService: CartService,
    private formBuilder: FormBuilder,
  ) {
  }
}

3. 폼 모델을 할당할 checkoutForm 프로퍼티를 CartComponent 클래스에 선언합니다.

src/app/cart/cart.component.ts

export class CartComponent {
  items;
  checkoutForm;
}

제품을 주문하려면 사용자가 이름과 주소를 입력해야 합니다. 그래서 이 정보를 저장하기 위해 name address 필드를 checkoutForm 프로퍼티에 할당되는 폼 모델에 선언해야 합니다. FormBuilder#group() 메소드를 다음과 같이 사용하면 됩니다:

src/app/cart/cart.component.ts

export class CartComponent {
  items;
  checkoutForm;

  constructor(
    private cartService: CartService,
    private formBuilder: FormBuilder,
  ) {
    this.items = this.cartService.getItems();

    this.checkoutForm = this.formBuilder.group({
      name: '',
      address: ''
    });
  }
}

5. 사용자는 이름과 주소를 폼에 입력해야 주문을 진행할 수 있습니다. 그리고 주문을 하고 나면 이 폼을 초기화하고 장바구니를 비우도록 구현해 봅시다.

cart.component.ts 파일에 onSubmit() 메소드를 정의합니다. 그리고 폼을 제출하고 나면 CartService#clearCart() 메소드를 실행해서 장바구니를 비우도록 구현합시다. (실제 운영하는 앱에서는 이 때 폼 데이터를 외부 서버에 보낼 것입니다.)

여기까지 구현하면 장바구니 컴포넌트 코드는 다음과 같은 모양이 될 것입니다.

 

src/app/cart/cart.component.ts

import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';

import { CartService } from '../cart.service';

@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.css']
})
export class CartComponent {
  items;
  checkoutForm;

  constructor(
    private cartService: CartService,
    private formBuilder: FormBuilder,
  ) {
    this.items = this.cartService.getItems();

    this.checkoutForm = this.formBuilder.group({
      name: '',
      address: ''
    });
  }

  onSubmit(customerData) {
    // 주문 로직은 여기에 구현합니다.
    console.warn('Your order has been submitted', customerData);

    this.items = this.cartService.clearCart();
    this.checkoutForm.reset();
  }
}

폼 모델은 컴포넌트 클래스에 정의되어 있습니다. 이 폼 모델을 화면과 연결하려면 템플릿에 주문 폼을 구성해야 합니다.

 

주문 폼 구성하기

다음에는 "장바구니" 페이지 맨 아래에 주문 폼을 추가해 봅시다.

1. cart.component.html 파일을 엽니다.

2. 템플릿 제일 아래에 HTML 폼을 추가합니다.

3. checkoutForm 프로퍼티와 form 태그는 formGroup 프로퍼티로 바인딩하면 됩니다. 그리고 폼을 제출하기 위해 "Purchase" 버튼도 추가합니다.

 

src/app/cart/cart.component.html

<form [formGroup]="checkoutForm">

  <button class="button" type="submit">Purchase</button>

</form>

4. form 태그에 ngSubmit 이벤트를 바인딩하면 폼을 제출하는 동작을 감지할 수 있습니다. ngSubmit 이벤트가 발생하면 checkoutForm 안에 있는 값을 인자로 사용해서 onSubmit() 메소드를 실행하도록 다음과 같이 작성합니다:

<form [formGroup]="checkoutForm" (ngSubmit)="onSubmit(checkoutForm.value)">
</form>

5. name address 입력 필드를 추가합니다. formControlName 어트리뷰트를 사용하면 checkoutForm 폼 컨트롤에 있는 name address 필드를 각각 바인딩할 수 있습니다. 여기까지 진행하면 컴포넌트 템플릿을 다음과 같이 작성할 수 있습니다

 

<h3>Cart</h3>

<p>
  <a routerLink="/shipping">Shipping Prices</a>
</p>

<div class="cart-item" *ngFor="let item of items">
  <span>{{ item.name }} </span>
  <span>{{ item.price | currency }}</span>
</div>

<form [formGroup]="checkoutForm" (ngSubmit)="onSubmit(checkoutForm.value)">

  <div>
    <label>Name</label>
    <input type="text" formControlName="name">
  </div>

  <div>
    <label>Address</label>
    <input type="text" formControlName="address">
  </div>

  <button class="button" type="submit">Purchase</button>
  
</form>

이제 장바구니에 제품을 몇개 추가하고 난 후에 사용자가 이름과 주소를 입력해서 주문을 요청할 수 있는 화면이 구성되었습니다

'옛날' 카테고리의 다른 글

Github Page로 블로그 만들기  (3) 2020.06.26
개인정보 처리방침  (0) 2020.05.08
Angular 튜토리얼 3  (0) 2020.02.20
Angular 튜토리얼 2  (0) 2020.02.19
Angular 튜토리얼 1  (0) 2020.02.18