개요
Angular에서 뷰에 데이터를 표시하는 데이터 바인딩에 이은 이번에는 데코레이터를 활용한 부모-자식 컴포넌트 간에 통신하는 방법에 대해 정리하려고 한다.
1. @Input()
@Input() 데코레이터는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달할 때 사용한다.
= 부모 -> 자식
// child.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-child',
template: `<p>안녕하세요, {{ name }}님!</p>`
})
export class ChildComponent {
@Input() name!: string;
}
-> @Input()은 name이라는 속성에 데코레이터를 붙여서, 외부에서 값을 주입할 수 있게 한다.
-> name! 에서 !는 TypeScript에서 '값이 나중에 들어올 거야'라는 의미로 사용하는 non-null assertio이다.
-> 템플릿에 전달받은 name을 바인딩 해 출력한다.
<!-- parent.component.html -->
<app-child [name]="'ho'"></app-child>
-> [name]="'ho'"는 자식 컴포넌트의 @Input() 속성인 name에 'ho'라는 값을 전달한다.
2. @Output()
자식 컴포넌트에서 이벤트를 발생시켜 부모 컴포넌트가 이를 처리하도록 만들 때 사용한다.
= 자식 -> 부모
// child.component.ts
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `<button (click)="sendMessage()">부모에게 메시지 보내기</button>`
})
export class ChildComponent {
@Output() message = new EventEmitter<string>();
sendMessage() {
this.message.emit('안녕하세요! 자식 컴포넌트입니다.');
}
}
-> @output() 데코레이터를 사용해 message라는 이벤트를 부모로 보낸다.
-> EventEmitter<string>()는 문자열 타입의 이벤트를 발생시키겠다는 의미이다.
-> sendMessage() 함수는 버튼 클릭 시 호출되고, message.emit()으로 부모에게 메시지를 전달한다.
<!-- parent.component.html -->
<app-child (message)="onMessageReceived($event)"></app-child>
// parent.component.ts
onMessageReceived(msg: string) {
console.log('자식으로부터 받은 메시지:', msg);
}
-> (message)="onMessageReceived($event)"는 자식 컴포넌트에서 발생한 message 이벤트를 부모 컴포넌트의 onMessageReceived() 메서드로 연결한다.
-> $event는 자식이 emit 한 값이다.
* $event
-> Angular 템플릿 문법에서 제공하는 기본 예약어로 자식 컴포넌트에서 emit한 값을 받아오기 위한 표현 방식 중 하나이다.
3. @Input(), @Output() 혼합
이번에는 @Input()과 @Output() 모두 적용해보자.
1. 부모는 자식에게 초기 이름을 전달
2. 자식이 버튼 클릭 시 이름을 변경하고 부모에게 알린다.
3. 부모는 자식에게서 받은 이름으로 상태를 업데이트한다.
자식
// child.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<p>현재 이름: {{ name }}</p>
<button (click)="changeName()">이름 바꾸기</button>
`
})
export class ChildComponent {
@Input() name!: string;
@Output() nameChange = new EventEmitter<string>();
changeName() {
const newName = 'TAEK';
this.nameChange.emit(newName);
}
}
부모
<!-- parent.component.html -->
<app-child [name]="parentName" (nameChange)="onNameChanged($event)"></app-child>
<p>자식이 바꾼 이름: {{ parentName }}</p>
// parent.component.ts
export class ParentComponent {
parentName = 'HO';
onNameChanged(newName: string) {
this.parentName = newName;
}
}
-> 초기 이름은 'HO'
-> 자식에서 'TAEK'이라는 이름을 보내면 parentName을 업데이트한다.
-> 이 값이 다시 자식에게 전달되기 때문에 이름이 화면에 즉시 반영된다.
처음 보면 헷갈리긴 한데 자주 쓰다보면 금방 익숙해질 것 같다!
'Web > Angular' 카테고리의 다른 글
[Angular] 데이터 바인딩(Data Binding)이란 (0) | 2025.03.24 |
---|---|
[Angular] angular bootstrap 개요 (0) | 2025.03.23 |
[Angular] Component 개요 (0) | 2025.03.20 |
[Angular] Angular란? (1) | 2025.03.19 |