コンポーネント間のデータ連携


親子の場合

子のメソッド呼出

親子でない場合


親から子へ: プロパティバインディングでデータを渡す

子クラス

@Input() uniqueName
@Input('child-property') property // 親から見える名前を変えるとき
@Input() sample

親テンプレート

<app-child1 [uniqueName]="parentProperty"
 [child-property]="parentProperty"
 sample="これは固定値を渡している"></app-child1>

子から親へ: 子のカスタムイベントをバインディング

子クラス

カスタムイベント実装

@Output('child-event') // 親から見えるイベント名
event = new EventEmitter<string>() // stringを渡す場合

// イベント発生のメソッド
send(value) {
  this.event.emit(value) // イベント発生
}

子テンプレート

<input #myinput type="text">
<button (click)="send(myinput.value)">入力文字列を親に送信</button>

親テンプレート

<app-child2 (child-event)="fromChild = $event"></app-child2>
<p>子から受信: {{fromChild}}</p>

子のメソッド呼出: 親テンプレートから

親テンプレート

<button (click)="child3.method(parentProperty)">子のメソッド呼出</button>
<app-child3 #child3></app-child3>

子クラス

property
method(value) {
  this.property = value
}

子のメソッド呼出: 親クラスから

親クラス

@ViewChild(Child4Component)
private child4: Child4Component

parentMethod(){
  this.child4.method(this.parentProperty)
}

親テンプレート

<button (click)="parentMethod()">子のメソッド呼出</button>
<app-child4></app-child4>

子クラス

property
method(value) {
  this.property = value
}

他のコンポーネントのメソッドを実行

親テンプレート

コンポーネントを示す参照変数をプロパティバインディングで渡す

<app-child5 [child6]="child6component"></app-child5>
<app-child6 #child6component></app-child6>

呼び出す側のクラス(child5)

@Input()
child6: Child6Component
method(value) {
  this.child6.method(value)
}

child5のテンプレート

<button (click)="method(true)">child6.method()</button>

呼び出される側のクラス(child6)

property
method(value) {
  this.property = value
}

サービス経由の受け渡し: EventEmitterやObservableで値を発行

EventEmitterクラス

代わりにObservableでも可

サービスクラス

SendService

import { ReplaySubject } from 'rxjs'

@Injectable({providedIn: 'root'}) // シングルトンなサービス
export class SendService {
  subject = new ReplaySubject(3) // 3回分保存
  send(value) {
    this.subject.next(value)
  }
}

親テンプレート

<app-child7></app-child7>
<app-child8></app-child8>
<app-child9></app-child9>

送信側: child7

constructor(private service: SendService) {} // サービス注入
send(value) {
  this.service.send(value)
}
<input #myinput type="text" value="hello">
<button (click)="send(myinput.value)">child7が送信</button>

受信側: child8

subscribe()メソッド

import { Subscription } from 'rxjs'
// 中略

constructor(private service: SendService) {} // サービス注入
subscription: Subscription // 受信キャンセル用
values = []
ngOnInit() {
  this.subscription = this.service.subject.subscribe(
    value => this.values.push(value)
  )
}
unsubscribe() {
  this.subscription.unsubscribe()
}
<p>child8が受信: {{values | json}}</p>
<button (click)="unsubscribe()">child8受信停止</button>