@Output Decorator
이번 포스트는 자식 Component에서 부모 Component로 데이터를 전달하기 위한 @Output
decorator에 대해서 알아보겠습니다.
자식 Component에서 부모 Component로 데이터를 전달하기 위해서는 EventEmitter
를 이용한 이벤트 처리를 하셔야 합니다. 즉, 자식 Component에서 발생한 event를 부모 Component가 event bidning
을 이용해 데이터를 받는 방식입니다.
코드레벨에서 알아보죠. 이전에 @Input decorator를 설명하면서 사용했던 예제를 좀 수정해서 사용하겠습니다.
아래는 search-box.component.ts
내용입니다.
import { Component, OnInit,
Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-search-box',
templateUrl: './search-box.component.html',
styleUrls: ['./search-box.component.css']
})
export class SearchBoxComponent implements OnInit {
_bookCategory: string;
//@Input() bookCategory:string;
//@Input('bookCategory') mySelected:string;
@Input()
set bookCategory(value: string) {
if( value != null ) {
// 추가적인 작업이 들어올 수 있습니다.
this._bookCategory = 'category: ' +value;
} else {
this._bookCategory = value;
}
}
@Output() searchEvent = new EventEmitter();
keyword = null;
constructor() { }
ngOnInit() {
}
setKeyword(keyword: string): void {
this.keyword = keyword;
this.searchEvent.emit({
keyword : `${this.keyword}`,
category: `${this._bookCategory.replace('category: ','')}`
});
}
inputChange(): void {
}
}
부모 Component에게 이벤트를 전달하기 위해 다음의 코드로 EventEmitter 객체를 생성하고 @Output decorator를 이용했습니다. 부모 Component는 searchEvent
이름으로 event binding 해야합니다.
@Output() searchEvent = new EventEmitter();
자식 Component에서 Search! 버튼을 눌렀을 때 setKeyword()
method가 호출되는데 이 안에서 searchEvent에 대한 이벤트를 발생시킵니다. 그러면서 부모 Component에게 전달할 데이터를 인자로 넣어줍니다.
this.searchEvent.emit({
keyword : `${this.keyword}`,
category: `${this._bookCategory.replace('category: ','')}`
});
이제 부모 Component에서 어떻게 event binding을 이용해서 데이터를 받는지만 살펴보면 됩니다.
아래는 book-search-main.component.html
입니다.
<div class="bookSearch-outer">
<div class="d-flex align-items-center p-3 my-3 text-white-50 bg-purple rounded box-shadow">
<img class="mr-3" src="assets/images/search-icon.png" alt="" width="48" height="48">
<div class="lh-100">
<h5 class="mb-0 text-white lh-100">Search Result : {{searchTitle}}</h5>
</div>
</div>
<div class="example-container">
<mat-form-field>
<mat-select placeholder="도서종류"
#bookCategorySelect
[(ngModel)]="selectedValue"
(ngModelChange)="changeValue(bookCategorySelect.value)">
<mat-option *ngFor="let category of bookCaterory"
[value]="category.value">
{{ category.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div>
<app-search-box [bookCategory]="displayCategoryName"
(searchEvent)="changeTitleBar($event)">
</app-search-box>
</div>
<div>
<app-detail-box></app-detail-box>
</div>
<div>
<app-list-box></app-list-box>
</div>
</div>
주의해서 보셔야 할 부분은
<app-search-box [bookCategory]="displayCategoryName"
(searchEvent)="changeTitleBar($event)">
</app-search-box>
입니다. event binding을 이용해서 searchEvent
이벤트가 발생하면 changeTitleBar()
method를 호출하고 인자를 받아서 처리하고 있네요. 인자 받는 방식도 유의해서 보셔야 합니다.
<h5 class="mb-0 text-white lh-100">Search Result : {{searchTitle}}</h5>
interpolation을 이용해 searchTitle 속성의 값을 View에 출력하고 있네요. 아마 changeTitleBar()
method안에서 내용이 결정될 듯 합니다.
마지막으로 book-search-main.component.ts
파일입니다.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-book-search-main',
templateUrl: './book-search-main.component.html',
styleUrls: ['./book-search-main.component.css',
'./offcanvas.css']
})
export class BookSearchMainComponent implements OnInit {
selectedValue = null;
displayCategoryName = null;
bookCaterory = [
{value: 'all', viewValue: '국내외도서'},
{value: 'country', viewValue: '국내도서'},
{value: 'foreign', viewValue: '국외도서'}
];
searchTitle = null;
constructor() { }
ngOnInit() {
}
changeValue(category: string): void {
for(let element of this.bookCaterory ) {
if(element.value == category) {
this.displayCategoryName = element.viewValue;
}
}
}
changeTitleBar(searchInfo) : void {
this.searchTitle = `${searchInfo.keyword} ( ${searchInfo.category} )`;
}
}
기본적인 개념은 이미 설명했으니 코드레벨에서 한번 천천히 살펴보시면 충분히 이해할 수 있을 듯 보입니다.
여기까지 작업한 내용을 실행해 정상적으로 동작하는지 확인하시면 될 듯 합니다.
자식 Component에서 부모 Component로 Event를 이용해서 데이터를 어떻게 전달하는지에 대해서 간단하게 살펴보았습니다.
다음 포스트는 부모 Component에서 자식 요소에 접근할 때 또 다른 방법으로 어떤 방법이 있는지 알아보도록 하겠습니다.
'Web Programming > Angular - TypeScript' 카테고리의 다른 글
Angular Content Projection 데이터공유 (0) | 2018.08.28 |
---|---|
Angular @ViewChild 데이터공유 (0) | 2018.08.28 |
Angular @Input 데이터공유 (0) | 2018.08.28 |
Angular Material Table (0) | 2018.08.28 |
Angular 예제 따라하기 (0) | 2018.08.28 |