EventEmitter と @Output を使って子コンポーネントから親コンポーネントのメソッドを呼び出す
Angular 4 で子コンポーネントから親コンポーネントのメソッドを呼び出す方法
EventEmitter と @Output を使用する
この方法は、子コンポーネントからイベントを発行し、親コンポーネントがそれを傍受するという仕組みです。
手順
- 子コンポーネント側
@Output
デコレータを使ってイベントを定義します。EventEmitter
オブジェクトをインスタンス化します。emit()
メソッドを使ってイベントを発行します。
- 親コンポーネント側
@Input
デコレータを使って子コンポーネントからイベントを受け取るためのプロパティを定義します。<ng-content>
ディレクティブを使って子コンポーネントのコンテンツを埋め込みます。- 親コンポーネントのテンプレートで、子コンポーネントから発行されたイベントをイベントバインディングを使って傍受します。
例
// 子コンポーネント (child.component.ts)
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-child',
template: '<button (click)="onClick()">子コンポーネントのボタン</button>',
})
export class ChildComponent {
@Output() onClickEvent = new EventEmitter<void>();
onClick() {
this.onClickEvent.emit();
}
}
// 親コンポーネント (parent.component.ts)
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<app-child (onClickEvent)="onChildClick()"></app-child>
`,
})
export class ParentComponent {
onChildClick() {
console.log('親コンポーネントで子コンポーネントのクリックイベントを傍受しました。');
}
}
@Input と InputBinding を使用する
この方法は、子コンポーネントから親コンポーネントにメソッドを呼び出すための関数をプロパティとして渡すという仕組みです。
- 親コンポーネント側
- 子コンポーネントに渡すメソッドを定義します。
- 子コンポーネント側
- 親コンポーネントから渡されたメソッドを呼び出すために、変数にバインディングします。
// 親コンポーネント (parent.component.ts)
import { Component, Output } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<app-child [callParent]="callParent"></app-child>
`,
})
export class ParentComponent {
callParent() {
console.log('親コンポーネントのメソッドが呼び出されました。');
}
}
// 子コンポーネント (child.component.ts)
import { Component, Input, Output } from '@angular/core';
@Component({
selector: 'app-child',
template: '<button (click)="callParentFunction()">子コンポーネントのボタン</button>',
})
export class ChildComponent {
@Input() callParent: Function;
callParentFunction() {
this.callParent();
}
}
補足
- 上記以外にも、サービスを使用したり、コンポーネント間通信用のライブラリを使用するなど、様々な方法で子コンポーネントから親コンポーネントのメソッドを呼び出すことができます。
- より詳細な情報は、Angular の公式ドキュメントを参照してください。
- [AtCoder Developers - Angular
Angular 4 で子コンポーネントから親コンポーネントのメソッドを呼び出すサンプルコード
親コンポーネント (parent.component.ts)
import { Component, Output } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<h2>親コンポーネント</h2>
<app-child (onClickEvent)="onChildClick()"></app-child>
`,
})
export class ParentComponent {
onChildClick() {
console.log('親コンポーネントで子コンポーネントのクリックイベントを傍受しました。');
}
}
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<h2>子コンポーネント</h2>
<button (click)="onClick()">子コンポーネントのボタン</button>
`,
})
export class ChildComponent {
@Output() onClickEvent = new EventEmitter<void>();
onClick() {
this.onClickEvent.emit();
}
}
このコードの説明
- 親コンポーネント
app-parent
は、app-child
という子コンポーネントをテンプレート内に埋め込んでいます。 - 子コンポーネント
app-child
は、onClick()
というメソッドとonClickEvent
という EventEmitter プロパティを定義しています。 onClick()
メソッドは、onClickEvent
イベントを発行します。- 親コンポーネント
app-parent
は、onClickEvent
イベントをイベントバインディングを使ってonChildClick()
メソッドにバインディングしています。 - 子コンポーネントのボタンをクリックすると、
onClick()
メソッドが呼び出され、onClickEvent
イベントが発行されます。 - 親コンポーネントの
onChildClick()
メソッドは、onClickEvent
イベントを傍受し、ログメッセージを出力します。
- このコードは、子コンポーネントから親コンポーネントにシンプルなデータを渡す例です。
- より複雑なデータを渡す場合は、イベントのペイロードにデータを含めることができます。
- また、親コンポーネントから子コンポーネントにデータを渡す方法もあります。
Angular 4 で子コンポーネントから親コンポーネントのメソッドを呼び出すその他の方法
// 親コンポーネント (parent.component.ts)
import { Component, Output } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<app-child [callParent]="callParent"></app-child>
`,
})
export class ParentComponent {
callParent() {
console.log('親コンポーネントのメソッドが呼び出されました。');
}
}
// 子コンポーネント (child.component.ts)
import { Component, Input, Output } from '@angular/core';
@Component({
selector: 'app-child',
template: '<button (click)="callParentFunction()">子コンポーネントのボタン</button>',
})
export class ChildComponent {
@Input() callParent: Function;
callParentFunction() {
this.callParent();
}
}
サービスを使用する
この方法は、子コンポーネントと親コンポーネントが共有するサービスを使用して、メソッドを呼び出すという仕組みです。
- サービスを作成する
- 子コンポーネントと親コンポーネントでサービスを注入する
- 子コンポーネントと親コンポーネントのコンストラクタにサービスを注入します。
- 子コンポーネントからサービスのメソッドを呼び出す
- 子コンポーネントから注入されたサービスを使用して、メソッドを呼び出します。
// サービス (app.service.ts)
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class AppService {
callParentMethod() {
console.log('親コンポーネントのメソッドが呼び出されました。');
}
}
// 親コンポーネント (parent.component.ts)
import { Component, Inject } from '@angular/core';
import { AppService } from './app.service';
@Component({
selector: 'app-parent',
template: `
<app-child [appService]="appService"></app-child>
`,
})
export class ParentComponent {
constructor(@Inject(AppService) private appService: AppService) {}
}
// 子コンポーネント (child.component.ts)
import { Component, Input, Inject } from '@angular/core';
import { AppService } from './app.service';
@Component({
selector: 'app-child',
template: '<button (click)="callParentMethod()">子コンポーネントのボタン</button>',
})
export class ChildComponent {
constructor(@Inject(AppService) private appService: AppService) {}
@Input() appService: AppService;
callParentMethod() {
this.appService.callParentMethod();
}
}
コンポーネント間通信用のライブラリを使用する
この方法は、コンポーネント間通信を容易にするためにライブラリを使用するという仕組みです。
Angular には、NgRx Store や ngxs/connect などのコンポーネント間通信用のライブラリがいくつかあります。これらのライブラリを使用すると、イベント、状態、サービスなどを介して、より複雑な方法でコンポー
angular