Angular 2
구성 요소 상호 작용
수색…
통사론
-
<element [variableName]="value"></element> //Declaring input to child when using @Input() method.
-
<element (childOutput)="parentFunction($event)"></element> //Declaring output from child when using @Output() method.
-
@Output() pageNumberClicked = new EventEmitter(); //Used for sending output data from child component when using @Output() method.
-
this.pageNumberClicked.emit(pageNum); //Used to trigger data output from child component. when using @Output() method.
-
@ViewChild(ComponentClass) //Property decorator is required when using ViewChild.
매개 변수
이름 | 값 |
---|---|
pageCount | 하위 구성 요소에 생성 할 페이지 수를 알려주는 데 사용됩니다. |
pageNumberClicked | 하위 구성 요소의 출력 변수 이름입니다. |
pageChanged | 자식 구성 요소 출력을 수신하는 부모 구성 요소의 함수입니다. |
부모 - @Input 및 @Output 속성을 사용한 자식 상호 작용
우리는 서비스에서 가져온 데이터를 보여주는 DataListComponent를 가지고 있습니다. DataListComponent에는 PagerComponent도 자식으로 있습니다.
PagerComponent는 DataListComponent에서 가져온 총 페이지 수를 기반으로 페이지 번호 목록을 만듭니다. 또한 PagerComponent는 사용자가 Output 속성을 통해 페이지 번호를 클릭하면 DataListComponent에 알릴 수 있습니다.
import { Component, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DataListService } from './dataList.service';
import { PagerComponent } from './pager.component';
@Component({
selector: 'datalist',
template: `
<table>
<tr *ngFor="let person of personsData">
<td>{{person.name}}</td>
<td>{{person.surname}}</td>
</tr>
</table>
<pager [pageCount]="pageCount" (pageNumberClicked)="pageChanged($event)"></pager>
`
})
export class DataListComponent {
private personsData = null;
private pageCount: number;
constructor(private dataListService: DataListService) {
var response = this.dataListService.getData(1); //Request first page from the service
this.personsData = response.persons;
this.pageCount = response.totalCount / 10;//We will show 10 records per page.
}
pageChanged(pageNumber: number){
var response = this.dataListService.getData(pageNumber); //Request data from the service with new page number
this.personsData = response.persons;
}
}
@NgModule({
imports: [CommonModule],
exports: [],
declarations: [DataListComponent, PagerComponent],
providers: [DataListService],
})
export class DataListModule { }
PagerComponent는 모든 페이지 번호를 나열합니다. 우리는 클릭 이벤트를 각각에 설정하여 부모에게 클릭 된 페이지 번호를 알릴 수 있습니다.
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'pager',
template: `
<div id="pager-wrapper">
<span *ngFor="#page of pageCount" (click)="pageClicked(page)">{{page}}</span>
</div>
`
})
export class PagerComponent {
@Input() pageCount: number;
@Output() pageNumberClicked = new EventEmitter();
constructor() { }
pageClicked(pageNum){
this.pageNumberClicked.emit(pageNum); //Send clicked page number as output
}
}
부모 - ViewChild를 사용한 자식 상호 작용
Viewchild는 부모와 자식 간의 일방적 인 상호 작용을 제공합니다. ViewChild가 사용될 때 하위 피드백이나 출력이 없습니다.
우리는 몇 가지 정보를 보여주는 DataListComponent를 가지고 있습니다. DataListComponent는 자식으로 PagerComponent를가집니다. 사용자가 DataListComponent를 검색하면 서비스에서 데이터를 가져 와서 PagerComponent에게 새 페이지 수를 기반으로 페이징 레이아웃을 새로 고치도록 요청합니다.
import { Component, NgModule, ViewChild } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DataListService } from './dataList.service';
import { PagerComponent } from './pager.component';
@Component({
selector: 'datalist',
template: `<input type='text' [(ngModel)]="searchText" />
<button (click)="getData()">Search</button>
<table>
<tr *ngFor="let person of personsData">
<td>{{person.name}}</td>
<td>{{person.surname}}</td>
</tr>
</table>
<pager></pager>
`
})
export class DataListComponent {
private personsData = null;
private searchText: string;
@ViewChild(PagerComponent)
private pagerComponent: PagerComponent;
constructor(private dataListService: DataListService) {}
getData(){
var response = this.dataListService.getData(this.searchText);
this.personsData = response.data;
this.pagerComponent.setPaging(this.personsData / 10); //Show 10 records per page
}
}
@NgModule({
imports: [CommonModule],
exports: [],
declarations: [DataListComponent, PagerComponent],
providers: [DataListService],
})
export class DataListModule { }
이 방법으로 하위 구성 요소에 정의 된 함수를 호출 할 수 있습니다.
부모 구성 요소가 렌더링 될 때까지 하위 구성 요소를 사용할 수 없습니다. 부모 AfterViewInit
생활 AfterViewInit
후크 전에 아이를 액세스하려고하면 예외가 발생합니다.
서비스를 통한 양방향 부모 - 자식 상호 작용
통신에 사용되는 서비스 :
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class ComponentCommunicationService {
private componentChangeSource = new Subject();
private newDateCreationSource = new Subject<Date>();
componentChanged$ = this.componentChangeSource.asObservable();
dateCreated$ = this.newDateCreationSource.asObservable();
refresh() {
this.componentChangeSource.next();
}
broadcastDate(date: Date) {
this.newDateCreationSource.next(date);
}
}
상위 구성 요소 :
import { Component, Inject } from '@angular/core';
import { ComponentCommunicationService } from './component-refresh.service';
@Component({
selector: 'parent',
template: `
<button (click)="refreshSubsribed()">Refresh</button>
<h1>Last date from child received: {{lastDate}}</h1>
<child-component></child-component>
`
})
export class ParentComponent implements OnInit {
lastDate: Date;
constructor(private communicationService: ComponentCommunicationService) { }
ngOnInit() {
this.communicationService.dateCreated$.subscribe(newDate => {
this.lastDate = newDate;
});
}
refreshSubsribed() {
this.communicationService.refresh();
}
}
하위 구성 요소 :
import { Component, OnInit, Inject } from '@angular/core';
import { ComponentCommunicationService } from './component-refresh.service';
@Component({
selector: 'child-component',
template: `
<h1>Last refresh from parent: {{lastRefreshed}}</h1>
<button (click)="sendNewDate()">Send new date</button>
`
})
export class ChildComponent implements OnInit {
lastRefreshed: Date;
constructor(private communicationService: ComponentCommunicationService) { }
ngOnInit() {
this.communicationService.componentChanged$.subscribe(event => {
this.onRefresh();
});
}
sendNewDate() {
this.communicationService.broadcastDate(new Date());
}
onRefresh() {
this.lastRefreshed = new Date();
}
}
AppModule :
@NgModule({
declarations: [
ParentComponent,
ChildComponent
],
providers: [ComponentCommunicationService],
bootstrap: [AppComponent] // not included in the example
})
export class AppModule {}