Angular 8コンポーネント通信ベース使用シーン(一)


コンポーネントインタラクション
親子コンポーネントインタラクション(一般的)
入出力属性Input,Output
最も基本的なシーンの一つで、非常に広く使われています.使用方法では、親コンポーネントのデータと子コンポーネントが宣言した変数をバインドし、子コンポーネントが内部レンダリングテンプレートに使用できることを保証します.主に、サブコンポーネントの内部コードフォーマットに注目します.

import { Component, OnInit, Input } from '@angular/core';
@Component({
  selector: 'app-children',
  templateUrl: './children.component.html',
  styleUrls: ['./children.component.scss']
})
export class ChildrenComponent implements OnInit {
  @Input() List: Array;
  constructor() { }
  ngOnInit() {
  }
}

@Input装飾器でこの変数が入力属性であることを宣言し、domのように属性をバインドするように使用しますが、少し違いがあります.
       :{{dataList.length}}

[]記号で現在のコンポーネントまたはページのデータにバインドします.このようなシーンデータの伝送方向は比較的単一で簡単であり,実際の開発ではサブコンポーネントも一部のデータを操作し,親コンポーネントも常に変化を受信することが多い.Angularでは、サブコンポーネント伝播イベントは@angular/coreからEventEmitterクラスを導入する必要があります.demoは次のようになります.
//     
@Output () removeHandler = new EventEmitter();
//         
removeAll(){
    this.List = [];
    this.removeHandler.emit(        );
}

テンプレート:

Name Phone
{{item.name}} {{item.phone}}

親コンポーネント:
removeData(e) {
    console.log(e);
    this.dataList = e; //                 
  }

onChangesライフサイクルインターセプト入力属性の変化
このほか、公式demoでは、サブコンポーネントバインドのプロパティをgetterおよびsetter処理する2つの傍受入力値の変化がローカルデータを更新するために提供されている.もう1つは開発において、コンポーネントの宣言周期フックngOnChanges関数を利用して処理し、上記demoを修正します.サブコンポーネント:
export class ChildrenComponent implements OnInit, OnChanges {
  @Input() List: Array;
  changeList = [];
  @Output() removeHandler = new EventEmitter();
  constructor() { }
  ngOnInit() {

  }
  ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
    let logs = [];
    if (!changes.List.firstChange) {
      logs = changes.List.currentValue;
      this.changeList = logs;
    }
  }
  removeAll() {
    this.changeList = [];
    this.removeHandler.emit(this.changeList);
  }
}
Name Phone
{{item.name}} {{item.phone}}

この例では、入力プロパティを1つだけバインドしているので、複数の場合はforループを使用して指定したデータを更新する必要があります.
ローカル変数インタラクション
公式定義:
親コンポーネントは、データバインドを使用してサブコンポーネントのプロパティを読み取る方法や、サブコンポーネントを呼び出す方法は使用できません.親コンポーネントテンプレートで、サブコンポーネントを表すローカル変数を新規作成し、この変数を使用してサブコンポーネントのプロパティを読み取り、サブコンポーネントを呼び出す方法
サブアセンブリの変更;
export class ChildrenComponent implements OnInit {
  // @Input() List: Array;
  changeList = [];
  // @Output() removeHandler = new EventEmitter();
  constructor() { }
  ngOnInit() {

  }
  addData(data) {
    this.changeList = [...this.changeList, data];
  }
  removeAll() {
    this.changeList = [];
  }
}

htmlテンプレートは変更されません.親コンポーネント:

:{{table.changeList.length}}
export class BasicComponent implements OnInit {

  constructor() { }
  name = '';
  phone = '';
  ngOnInit() {

  }
}

コンポーネント内の論理は、バインドされたtableによってサブコンポーネントのプロパティとメソッドに直接アクセスできるため、削除されます.
親コンポーネント呼び出し@ViewChild
コンポーネント内の属性とメソッドに直接アクセスする必要がある場合があります.ローカル変数は適用されません.@ViewChild()の使用を検討してください.
親コンポーネントの変更:

:{{dataList.length}}
import { Component, OnInit, ViewChild } from '@angular/core';
import { ChildrenComponent } from '../children/children.component';
@Component({
  selector: 'app-basic',
  templateUrl: './basic.component.html',
  styleUrls: ['./basic.component.scss']
})
export class BasicComponent implements OnInit {
  @ViewChild(ChildrenComponent, { static: false })
  private children: ChildrenComponent;
  constructor() { }
  name = '';
  phone = '';
  dataList = [];
  ngOnInit() {

  }
  addData() {
    this.dataList = [...this.dataList, {
      name: this.name,
      phone: this.phone
    }];
    this.children.addData({
      name: this.name,
      phone: this.phone
    });
  }
  removeAll() {
    this.dataList = [];
    this.children.removeAll();
  }
}

子コンポーネントに初期化操作がある場合は、親コンポーネントのAfterView宣言サイクルで初期化できます.
任意のコンポーネント間-サービス(Service)
ビジネス内の比較的多くのインタラクションには、親子コンポーネントの関連が存在しないことが多いので、サービスインタラクションを使用するのは良い選択です.
サービスファイルコード:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class WorkerListService {
  workList = [];
  workListSource = new Subject();
  private workListSource$ = this.workListSource.asObservable();
  constructor() { }
  addInfo(info) {
    this.workList = [...this.workList, info];
    this.workListSource.next(this.workList);
  }
  updateWorkList(infos: Array) {
    this.workList = infos;
    this.workListSource.next(this.workList);
  }

}

説明の下のコード部分では、まず1つのデータが購読できる前提は1つのObservableタイプでなければならない.通常の配列of(SomeArray)に対してはすでに1つのObservableタイプで購読可能であり、返されるhttpリクエストに対してもObservableタイプであり、ページでは購読処理を直接接続することができ、Ng公式ドキュメントではObservableタイプを列挙する説明がある.詳細については、next()メソッドを使用して、この観察可能なオブジェクトに更新内容を通知します.これにより、サブスクリプション(subscribe)は更新後の情報をキャプチャします.
元の親コンポーネント:
import { Component, OnInit } from '@angular/core';
import { WorkerListService } from '../worker-list.service';
@Component({
  selector: 'app-basic',
  templateUrl: './basic.component.html',
  styleUrls: ['./basic.component.scss']
})
export class BasicComponent implements OnInit {
  constructor(
    private workListService: WorkerListService
  ) { }
  name = '';
  phone = '';
  dataList = [];
  ngOnInit() {
    this.workListService.workListSource.subscribe(res => {
      this.dataList = res;
    });
  }
  addData() {
    this.workListService.addInfo({
      name: this.name,
      phone: this.phone
    });
  }
  removeAll() {
    this.dataList = [];
    this.workListService.updateWorkList(this.dataList);
  }
}

原子コンポーネント:
import { Component, OnInit } from '@angular/core';
import { WorkerListService } from '../worker-list.service';
@Component({
  selector: 'app-children',
  templateUrl: './children.component.html',
  styleUrls: ['./children.component.scss']
})
export class ChildrenComponent implements OnInit {
  changeList = [];
  constructor(
    private workListService: WorkerListService
  ) {
    this.workListService.workListSource.subscribe(res=>{
      this.changeList = res;
    });
  }
  ngOnInit() {

  }
}

これにより、コンポーネントが親子コンポーネントであるかどうかを心配することなく、最新のデータ更新をいつでも取得できることが保証され、最も一般的な方法でもあります.