web-dev-qa-db-ja.com

子はAngular 2の親イベントをリッスンします

angularドキュメントには、親からの子イベントのリスニングに関するトピックがあります。それはいいです。しかし、私の目的は逆です!私のアプリには、管理ページ(サイドバーメニュー、タスクバー、ステータスなど)のレイアウトビューを保持する「admin.component」があります。この親コンポーネントでは、管理者の他のページ間でメインビューを変更するためにルーターシステムを構成しました。問題は、変更後のものを保存することです。ユーザーはタスクバー(admin.componentに配置されています)の[保存]ボタンをクリックし、子コンポーネントはスタッフを保存するためにそのクリックイベントをリッスンする必要があります。

64
Hamed Hamedi

このドキュメントはあなたに役立つと思います:

実際、親がその子に提供する観察可能/サブジェクトを活用できます。そんな感じ:

@Component({
  (...)
  template: `
    <child [parentSubject]="parentSubject"></child>
  `,
  directives: [ ChildComponent ]
})
export class ParentComponent {
  parentSubject:Subject<any> = new Subject();

  notifyChildren() {
    this.parentSubject.next('some value');
  }
}

子コンポーネントは、このサブジェクトを単純にサブスクライブできます。

@Component({
  (...)
})
export class ChildComponent {
  @Input()
  parentSubject:Subject<any>;

  ngOnInit() {
    this.parentSubject.subscribe(event => {
      // called when the notifyChildren method is
      // called in the parent component
    });
  }

  ngOnDestroy() {
    // needed if child gets re-created (eg on some model changes)
    // note that subsequent subscriptions on the same subject will fail
    // so the parent has to re-create parentSubject on changes
    this.parentSubject.unsubscribe();
  }

}

それ以外の場合は、このようなサブジェクトを含む共有サービスを同様の方法で活用できます...

85

後世のためにこれに対するより一般的な解決策:単にViewChildへの参照を取得し、そのメソッドの1つを直接呼び出します。

@Component({
  selector: 'app-child'
})
export class ChildComponent {

  notifyMe() {
    console.log('Event Fired');
  }
}

@Component({
  selector: 'app-parent',
  template: `<app-child #child></app-child>`
})
export class ParentComponent {

  @ViewChild('child')
  private child: ChildComponent;

  ngOnInit() {
    this.child.notifyMe();
  }
}
105
Stephen Paul

ここで質問を正しく理解すれば、より素朴なアプローチが可能になるかもしれません。仮定-

  • OPには、親コンポーネントに保存ボタンがあります
  • 保存する必要があるデータは子コンポーネントにあります
  • 子コンポーネントが必要とする可能性のある他のすべてのデータには、サービスからアクセスできます。

親コンポーネント内

<button type="button" (click)="prop1=!prop1">Save Button</button>
<app-child-component [setProp]='prop1'></app-child-component>

そして、子供に..

prop1:boolean;
  @Input()
  set setProp(p: boolean) {
    // -- perform save function here
}

これは、ボタンクリックを子コンポーネントに送信するだけです。そこから、子コンポーネントはデータを個別に保存できます。

編集:親テンプレートからのデータもボタンクリックとともに渡す必要がある場合は、このアプローチでも可能です。その場合はお知らせください。コードサンプルを更新します。

9
charsi