Component Interaction
Component Interaction
컴포넌트 제작 및 parent와의 interaction
Component
anguars는 컴포넌트의 집합이다. 컴포넌트가 모여서 하나의 모듈이 생성된다.
@Component({
selector: 'app-mycomponent',
})
위와 같이 정의하고 module에서 declarations 하면 모듈의 하위 컴포넌트에서 아래와 같이 사용할 수 있다.
<app-mycomponent></app-mycomponent>
Interaction
parent와 호출되어지는 컴포넌트에서는 [], ()를 이용하여 상호 데이타를 주고 받을 수 있다
[] 는 parent에서 하위 컴포넌트로 데이타를 보낼 때, ()은 parent 에서 하위 컴포넌트의 데이타를 받을 때 사용 할 수 있다
@Input() child: {futbols: Array<boolean>, name: string, id: number};
@Output() voted: EventEmitter<number> = new EventEmitter<number>()
@Input() : []from parent to component
@Output() : ()to parent from component
parent
<app-child [child]="childData" (voted)="resultReceive($event)"></app-child>
- [child]="childData": childData 를 child 변수로 child로 보낸다.
- (voted)="resultReceive($event)" : child에서 생성한 voted라는 이벤트를 받아서 resultReceive 를 실행한다.
child component
import { Input, Output, EventEmitter } from '@angular/core';
..........
@Component({
selector: 'app-child',
})
export class ChildComponent {
@Input() child: {futbols: Array<boolean>, name: string, id: number};
@Output() voted = new EventEmitter<boolean>();
vote(agreed: boolean) {
this.voted.emit(agreed);
}
}"
parent component
<app-voter (voted)="onVoted($event)"></app-voter>
onVoted(agreed: boolean) {
agreed ? this.agreed++ : this.disagreed++;
}
동일 변수 선택
child component 에서 onDataChange 를 사용하여 받는다.
@Input() data: TaskBook;
@Output() dataChange = new EventEmitter<TaskBook>();
onDataChange() {
this.dataChange.emit(this.data);
}
import { Component, Input } from '@angular/core';
@Input() hero: Hero; 바로 변수로 처리 // [hero] 를 받아서 hero의 변수에 저장
@Input('master') masterName: string; // [master] 를 받아서 masterName 에 저장
import { Component } from '@angular/core';
import { HEROES } from './hero';
@Component({
selector: 'app-hero-parent',
template: `
<h2>{{master}} controls {{heroes.length}} heroes</h2>
<app-hero-child *ngFor=""let hero of heroes""
[hero]="hero"
[master]="master"
>
</app-hero-child>
`
})
export class HeroParentComponent {
heroes = HEROES;
master = 'Master';
}
위의 경우는 바로 변수를 받아서 사용하는 예이지만 아래와 같이 변수를 받아서 한번 더 처리하여 사용 가능하다.
@Input()
set name(name: string) {
this._name = (name && name.trim()) || '<no name set>';
}
get name(): string { return this._name; } // 초기 1회만 세팅됨
아래는 경우는 parent의 값이 실시간으로 변경될때 그 변경된 값을 받아 새로이 처리하는 방식이다.
ngOnChanges 와 SimpleChange 를 이용하여 실시간 데이타 변경을 감시 할 수 있다.
import { Component, Input, OnChanges, SimpleChange } from '@angular/core';
@Component({
selector: 'app-version-child',
template: `
<h3>Version {{major}}.{{minor}}</h3>
<h4>Change log:</h4>
<ul>
<li *ngFor=""let change of changeLog"">{{change}}</li>
</ul>
`
})
export class VersionChildComponent implements OnChanges {
@Input() major: number;
@Input() minor: number;
changeLog: string[] = [];
ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
let log: string[] = [];
for (let propName in changes) {
let changedProp = changes[propName];
let to = JSON.stringify(changedProp.currentValue);
if (changedProp.isFirstChange()) {
log.push(`Initial value of ${propName} set to ${to}`);
} else {
let from = JSON.stringify(changedProp.previousValue);
log.push(`${propName} changed from ${from} to ${to}`);
}
}
this.changeLog.push(log.join(', '));
}
}
계속해서 listen을 원할 경우
ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
for (const propName in changes) {
if (changes.hasOwnProperty(propName)) {
const changedProp = changes[propName];
console.log(propName, changedProp);
if (propName === 'active') {
this.active = changedProp.currentValue;
}
}
}
}
Input OutPut 동시사용
@Input() activeField?: SudokuField;
@Output() activeFieldChange = new EventEmitter<SudokuField>();"<su-grid [(activeField)]="activeField"></su-grid>
this.activeFieldChange .emit(this.data);