Contents

앵귤러 자식 부모 컴포넌트 간 데이터 전달

https://angular.kr/guide/inputs-outputs

앵귤러에서 @Input, @Output 데코레이터를 사용하면 부모 / 자식 컴포넌트 간 데이터를 전달할 수 있다.

부모 -> 자식 데이터 전달

@Input 데코레이터를 사용해서 부모 컴포넌트에서 자식 컴포넌트로 특정 프로퍼티를 전달할 수 있다. @Input 심볼은 '@angular/core' 라이브러리에 포함되어 있다.

import { Component, Input } from '@angular/core'; // Input 심볼을 로드합니다.
export class ItemDetailComponent {
  @Input() item = ''; // 프로퍼티에 @Input() 데코레이터를 지정합니다.
}

위 코드에서 @Input 데코레이터는 다음과 같은 역할을 한다.

  • string 타입으로 선언된 item 프로퍼티가 입력 프로퍼티라는 것을 지정
  • 이 때 @Input 프로퍼티에는 number, string, boolean, object 등 어떤 타입도 전달 가능
  • 해당 프로퍼티에 올바른 타입으로 데이터를 전달하는 것은 부모 컴포넌트의 책임

부모 컴포넌트 프로퍼티 바인딩

<app-item-detail [item]="currentItem"></app-item-detail>

자식 컴포넌트 셀렉터 <app-item-detail>이 설정되어 있다는 가정 하에,

위와 같이 프로퍼티 바인딩을 통해 부모 컴포넌트의 currentItem을 자식 컴포넌트의 item 프로퍼티로 바인딩할 수 있다.

즉 사용법을 정리하자면 아래와 같다. 헷갈리지 말자. <자식컴포넌트-셀렉터 [자식컴포넌트-프로퍼티]="부모컴포넌트-프로퍼티"></자식컴포넌트-셀렉터>

@Input()의 변화 감지

OnChanges를 활용한다.

자식 -> 부모 데이터 전달

역으로 자식 컴포넌트에서 부모 컴포넌트로 프로퍼티를 전달하려면 어떻게 해야 할까?

  • @Output 데코레이터를 사용한다.
  • @Output 데코레이터는 자식 컴포넌트의 프로퍼티 중 부모 컴포넌트의 프로퍼티로 데이터를 전송하는 프로퍼티를 지정하는 역할을 한다.

생김새는 비슷하지만, 부모 -> 자식으로 프로퍼티를 전달하는 것과는 약간 결이 다르다.

  • 자식 컴포넌트에서 부모 컴포넌트로 프로퍼티를 보내려면 이벤트를 발생시켜야 한다.
  • 따라서 @Output 데코레이터는 반드시 EventEmitter 타입의 프로퍼티에 선언해야 한다.

자식 컴포넌트에 아래과 같이 프로퍼티를 지정했다고 하자.

export class ItemOutputComponent {

  @Output() newItemEvent = new EventEmitter<string>();

  addNewItem(value: string) {
    this.newItemEvent.emit(value);
  }
}

코드만 봐도 대충 느낌은 온다. addNewItem() 함수가 실행되었을 때 newItemEvent 프로퍼티를 통해서 자식 컴포넌트는 부모 컴포넌트로 string 타입 프로퍼티를 전달할 것이다.

핵심은, 자식 컴포넌트에서 부모 컴포넌트로의 프로퍼티 전달은 이벤트를 통해서 이뤄진다는 것이다.

트러블 슈팅 : 왜 내 @Input 에는 항상 undefined일까

이제 배웠으니 실제로 써볼까? 어라..? 왜 내 @Input 프로퍼티에는 값이 들어오지 않을까?

https://stackoverflow.com/questions/42123170/input-value-is-always-undefined

이해하려면 앵귤러의 라이프 사이클 훅에 대한 이해가 필요하다.. 하지만 전부를 다 이해하기엔 시간이 없으니 다음에 알아보도록 하자 (꼭!)

핵심은 부모 - 자식 컴포넌트 간 프로퍼티 전달은 ngOnInit() 에서 초기화 되며 일어난다. 나는 생성자에서 console.log()를 찍고 있었고, 생성자 이후에 ngOnInit() 이 일어나기 때문에 undefined가 콘솔에 찍히고 있었다.

관련 로직을 생성자가 아닌 ngOnInit()으로 이관하니 예상했던 대로 잘 동작하는 것을 볼 수 있었다.

한편으로 객체의 프로퍼티로써 데이터를 전달할 때에는 생성자를 통해 데이터를 받아올 수 있는 것 같다..

이 부분은 아직 확인되지는 않아서~ 나중에 라이프 사이클 훅을 공부할 때 다시 봐야겠다.