私はAngularをもっと上手にしようとしていますが、子供と親のコミュニケーションのベストプラクティスを知りたいです。現在作業しているアプリはAngularにあります。6。@ ViewChild、@ Outputを使用するか、サービスを作成して、子と親のコンポーネント間で通信できることを知っています。コミュニケーションを行う別の方法はありますか?そうでない場合は、これらの3つのどれがより良いのか、そしてその理由は?
以下に簡単な例を示します。
子HTML
<button (click)="onLinkedClicked();">Click me</button>
子供TS
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
.
.
.
export class showcaseMenuComponent implements OnInit {
@Output() public linkedClicked = new EventEmitter<String>();
constructor() {}
onLinkedClicked() {
console.log('on click child');
this.linkedClicked.emit('collapsed');
}
}
親HTML
<showcase-menu #topNavMenu
[showBranding]="false"
[showSearch]= "false"
(linkedClicked)="linkToggler($event)">.
</showcase-menu>
親TS
.
.
.
navMenuState: string;
.
.
.
linkToggler($event) {
console.log("partent");
this.navMenuState = $event;
}
明らかにそれはあなたが何をしたいかに依存します。
@入力
_@Input
_を使用することにより、子コンポーネントに直接パラメーターを渡します。さらに、コンポーネントを一方を他方の内側に配置することでコンポーネントを結合しています。このアプローチは便利でシンプルです。
子コンポーネントが特定のオブジェクトを共有する親コンポーネントに統合されていることを確認し、同期メカニズムを気にする必要がない場合は、この方法が適しています。
つまり、オブジェクトのプロパティを変更しても、オブジェクト参照は同じであるため、親とコンポーネントに更新されます。ただし、1つのコンポーネントでオブジェクト参照を変更する場合(たとえば、新しいインスタンスをインスタンス化するか、リモートサービスで新しいオブジェクトを取得する場合)、他のコンポーネントはオブジェクトの変更を検出できないため、データの不整合が発生します。
@出力
_@Output
_を使用すると、イベントが上方に放出されるため、このアプローチは、何かが発生したことを親に伝えたい場合に役立ちます。データ交換は可能ですが、それは物事の焦点ではありません。
焦点は、何かが発生することです。たとえば、ウィザードではいくつかのステップがあり、各ステップはその特定のステップが完了したことを親コンポーネントに通知できます。親は何が起こったのかを知る必要はありませんが、それだけが起こったので、次のステップに進むことができます。
@ ViewChild
_@ViewChild
_を使用すると、子コンポーネントの参照を親コンポーネントに取得できます。
ロジックを組み合わせて、親に特定の子コンポーネントを機能させる必要があります。
これは、子コンポーネントのメソッドを親コンポーネントに呼び出したいときに便利です。
ウィザードの例を使用すると、この状況について考えることができます。
@Output
_イベントが親に発行されますサービス
外部サービスを使用すると、データを管理および更新する責任がある1つの外部オブジェクトにデータを集中化できます。
これは、リモートサービスからデータを取得したり、データオブジェクト参照を再割り当てしたりできる状況に適したアプローチです。
さらに、このアプローチにより、すべてのコンポーネントを互いに分離しています。彼らは他人の行動を心配することなく自分で働くことができます。
通常、Subject
はサービス通信に使用されます。
あなたは見つけることができます ここにドキュメント
件名VS @出力
Subject
は、データ駆動型のアプローチを使用しています。 _@Output
_は、イベントドリブンアプローチ、またはより良い リアクティブプログラミング アプローチを使用します
したがって、イベントが発生したことを伝えたい場合は_@Output
_が推奨される方法であり、データが変更されたことを伝えるにはSubject
が推奨される方法です。
サブジェクトは、監視可能な値のソースであり、監視可能なオブジェクト自体でもあります。 Observableと同じように、Subjectをサブスクライブできます。
つまり、Subject
を使用して特定の変数または値(Subject
をObserver
として)を観察でき、観察された値の変化を検出して一種のイベントを発行します。
その間、サブジェクトのイベントをサブスクライブすることで、Subject
(Subject
as Observable
)を監視している他の多くのオブザーバーを作成できます。
被験者の観察値が変化した場合、すべての被験者の加入者に通知されます。
例として、発券アプリケーションがあります。 1人のユーザーが、残りの無料の場所を表示するコンポーネントをロードします。彼はどの場所を選ぶべきか考えています。その間、別のユーザーがチケットを購入したため、彼の場所は利用できなくなりました。これで、最初のユーザーはその場所を利用不可として表示するはずなので、リモートサービスに要求するデータを更新する必要があります(おそらくポーリングアルゴリズムを使用します)。新しいデータが取得されると、新しいデータをSubject.next()
に渡します。 Subject
は、観測された値が変更されたことを検出し、値が変更されたことをすべてのサブスクライバーに通知します。明らかにSubject
新しいデータをサブスクライバーに渡します。
あなたが示した状況では、私の好みは@Output
を使用することです。
クリックされたリンクが大きな問題になる可能性は低いので、サービスが意味をなさないと思います。
@ViewChild
は機能しますが、コンポーネントの再利用性が低下します。別の親の内部で子コンポーネントを再利用する場合は、コードをコピーする必要があります。
@Output
を使用すると、別の親で子コンポーネントを使用する場合、追加のコードをコピーする必要がなく、@Output
イベントに非常に簡単にバインドできます。
複数のコンポーネント間でデータを共有することができます
サービスを作成
import { Injectable } from '@angular/core';
import {Subject} from 'rxjs/Subject';
@Injectable()
export class ChildParentService {
data=new Subject();
constructor() { }
}
次の場合は、親と子の間のサービス通信を使用します。
1.親コンポーネントから複数の子コンポーネントにデータを渡したい。
2.いくつかの子コンポーネントには、親コンポーネントにディスパッチされる同じEventEmitterがあります。