サーチ…


構文

  • <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 life cyle hookの前に子にアクセスしようとすると、例外が発生します。

サービスによる双方向の親子関係

コミュニケーションに使用されるサービス:

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 {}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow