Angular에서 사용자 정의 폼 컨트롤 만들기: ControlValueAccessor와 FormGroup 활용

agnusdei·2023년 10월 6일

Angular 애플리케이션에서 폼 컨트롤을 사용자 정의하고 제어하려면 ControlValueAccessorFormGroup를 이해하고 활용해야 합니다. 이 블로그 글에서는 이러한 개념을 상세하게 설명하고, 간단한 예제를 통해 실제로 어떻게 구현하는지 살펴보겠습니다.

ControlValueAccessor 개요

ControlValueAccessor는 Angular에서 컴포넌트를 사용자 정의 폼 컨트롤로 래핑하고, Angular 폼 모델과 상호작용하기 위한 인터페이스입니다. 이를 구현한 컴포넌트는 모델 값을 설정하고 폼 컨트롤 값을 업데이트할 수 있습니다. 이를 위해 네 가지 주요 메서드를 구현해야 합니다.

  1. registerOnChange(fn: any): 폼 컨트롤 값이 변경될 때 호출되는 콜백 함수를 등록합니다.
  2. registerOnTouched(fn: any): 폼 컨트롤이 터치(사용자 상호작용)될 때 호출되는 콜백 함수를 등록합니다.
  3. writeValue(obj: any): 모델로부터 폼 컨트롤로 값을 쓰는 메서드로, 초기값을 설정하거나 외부에서 값을 주입하는 데 사용됩니다.
  4. setDisabledState(isDisabled: boolean): 폼 컨트롤을 활성화 또는 비활성화하는 메서드로, 컨트롤의 상태를 관리합니다.

ControlValueAccessor 구현

간단한 사용자 정의 입력 요소를 생성하고 ControlValueAccessor를 구현하여 폼 컨트롤과 상호작용하는 방법을 살펴보겠습니다.

import { Component, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-custom-input',
  template: `
    <input type="text" [(ngModel)]="value" (input)="onChange($event.target.value)" [disabled]="disabled">
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CustomInputComponent),
      multi: true
    }
  ]
})
export class CustomInputComponent implements ControlValueAccessor {
  value: string = '';
  disabled: boolean = false;

  // ControlValueAccessor 구현
  onChange: any = () => {};
  onTouch: any = () => {};

  writeValue(value: any): void {
    this.value = value;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouch = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }
}

사용 예제

위에서 구현한 CustomInputComponent를 다른 컴포넌트에서 사용하는 예제를 살펴보겠습니다.

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

@Component({
  selector: 'app-root',
  template: `
    <form [formGroup]="formGroup">
      <app-custom-input formControlName="customInput"></app-custom-input>
    </form>
    <button (click)="toggleDisabled()">Toggle Disabled</button>
  `
})
export class AppComponent {
  formGroup: FormGroup;

  constructor(private formBuilder: FormBuilder) {
    this.formGroup = this.formBuilder.group({
      customInput: ['Initial Value']
    });
  }

  toggleDisabled() {
    const customInputControl = this.formGroup.get('customInput');
    if (customInputControl) {
      customInputControl.disabled ? customInputControl.enable() : customInputControl.disable();
    }
  }
}

작동 방법

  1. ControlValueAccessor 구현: CustomInputComponent에서는 ControlValueAccessor를 구현하여 폼 컨트롤과의 상호작용을 처리합니다.

    • writeValue 메서드를 사용하여 초기값을 설정하거나 외부에서 값을 주입합니다.
    • registerOnChangeregisterOnTouched 메서드를 사용하여 폼 컨트롤의 변경 이벤트와 터치 이벤트를 처리하고 콜백 함수를 등록합니다.
    • setDisabledState 메서드를 사용하여 폼 컨트롤을 활성화 또는 비활성화합니다.
  2. 템플릿과 폼 연동: 컴포넌트 템플릿에서는 ngModel 또는 formControlName을 사용하여 CustomInputComponent와 폼 컨트롤 간의 연결을 설정합니다.

  3. 사용 예제: CustomInputComponent를 다른 컴포넌트에서 사용하여 폼을 구성하고 사용자 정의 입력 요소를 활용합니다.

이제 ControlValueAccessorFormGroup를 활용하여 사용자 정의 폼 컨트롤을 만드는 방법을 상세하게 이해하셨을 것입니다. 이러한 기술을 사용하면 Angular에서 폼 컨트롤을 더욱 유연하게 다룰 수 있으며, 재사용 가능한 사용자 정의 입력 요소를 생성할 수 있습니다.

0개의 댓글