Angular Control Value Accessor

라코마코·2021년 9월 30일
1

Angular

목록 보기
4/6

주의! 이 글은 철저히 본인의 기억을 다시 떠올리기 위해서 만든 글입니다.

CVA a.k.a Control Value Accessor

앵귤러의 중요한 기능이지만 사용할 기회가 적어서 ( 대략 까먹을때쯤에 필요해짐... ) 나중을 위해서 블로깅 해둡니다.

C.V.A란?

Angular Forms API중 하나인데 컴포넌트와 DOM Element간 커넥션을 만들어 form을 조작하는 기능이다.
( 먼소리지... )

한 줄로 요약하면 컴포넌트를 Form의 기능처럼 사용하는 방법이다.

Usage

ctrl = new FormControl('');

이렇게 FormControl가 있는 컴포넌트에서

<app-custom-input [formControl]="ctrl"></app-custom-input>

CVA 컴포넌트에 FormControl 디렉티브를 사용해서 붙이면 사용이 가능하다.

Usage C.V.A

일단 CVA 전체 코드 먼저 투척한다.

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

@Component({
  selector: 'app-custom-input',
  templateUrl: './custom-input.component.html',
  styleUrls: ['./custom-input.component.css'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CustomInputComponent),
      multi: true,
    },
  ],
})
export class CustomInputComponent implements ControlValueAccessor {
  onChange: any = () => {}; // UI 변경시 실행해야하는 함수, 위 Form에 전파됨 CVA -> form
  onTouch: any = () => {}; // UI Element touch시 실행해야하는 함수 Form에 전파됨 CVA -> form
  val = '';

  // Form에서 값이 변경될시 CVA 값을 바꾸는 함수 form -> CVA
  writeValue(value: any): void {
    this.val = value;
  }

  // 함수 등록용 함수
  registerOnChange(fn: any): void {
    console.log('registerOnChange run');
    this.onChange = (value) => {
      console.log('change Run');
      fn(value);
    };
  }

  // onTouched 함수 등록용 함수
  registerOnTouched(fn: any): void {
    console.log('registerOntouched run');
    this.onTouch = (value) => {
      console.log('touch Run');
      fn(value);
    };
  }

  inputRun(event: Event) {
    const inputElement = event.target as HTMLInputElement;
    this.val = inputElement.value;
    this.onChange(this.val);
    this.onTouch(this.val);
  }
}

코드를 하나씩 까보자.

  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CustomInputComponent),
      multi: true,
    },
  ],

C.V.A 컴포넌트에는 항상 다음과 같은 providers가 붙어야한다. provide로 NG_VALUE_ACCESSOR 토큰을 내려보내줘야하고 useExisting으로 자신을 내보내야 C.V.A 가 된다고 한다.

CVA는 다음과 같은 메소드들이 있다.

writeValue, onChange, onTouch, registerOnChange, registerOnTouced

writeValue 함수는 form -> CVA로 데이터가 전파되는 함수이다.

form의 값이 변경되면 writeValue 함수도 호출되서 C.V.A 상태를 이곳에서 변경할 수 있다.

  // Form에서 값이 변경될시 CVA 값을 바꾸는 함수 form -> CVA
  writeValue(value: any): void {
    this.val = value;
  }

registerOnChange, registerOnTouced은 컴포넌트가 실행되면 함께 실행되는 함수다

각각 매개변수로 onChange, onTouch 함수를 보내는데 이를 C.V.A에서 저장하여 나중에 활용해야한다.

onChange, onTouch 함수는 CVA -> form으로 데이터를 전파하는 함수다.

  inputRun(event: Event) {
    const inputElement = event.target as HTMLInputElement;
    this.val = inputElement.value;
    this.onChange(this.val);
    this.onTouch(this.val);
  }

이경우 위의 ctrl값이 onChange 함수에 의해서 변경된다.

E.O.D

0개의 댓글