Angular 8:在 child 组件中调用该方法后,使用 ViewChild 获取从 child 到 parent 的方法结果

Angular 8: using ViewChild get a method result from a child to parent after that method is invoked in child component

在我的 child 组件中,我有两个按钮,如下所示:

child-component.html

<div>
   <button (click)="getFirstData()">First</button>
   <button (click)="getLastData()" >Last</button>
</div>

child-component.ts:

export class ChildComponent implements OnInit, AfterViewInit {
  firstItem: number;
  lastItem: number;

  constructor() {
  }

  ngOnInit() {
  }

  ngAfterViewInit(): void {
  }

  getFirstData() {
    this.firstItem = 1;
    return this.firstItem;
  }

  getLastData() {
    this.lastItem= 10;
    return this.lastItem;
  }

}

在 parent 组件中,我需要在从 child 组件调用相应方法后接收 firstItemlastItem 数据。当我尝试在 parent 组件中使用 AfterViewInit 生命周期挂钩中的 ViewChild 获取它时,如下所示:

parent-component.ts

export class ParentComponent implements OnInit, AfterViewInit {
  @ViewChild(ChildComponent, {static: true}) child: ChildComponent;

  first: number;
  last: number;

  ngOnInit() {
  }

  ngAfterViewInit() {

    console.log('first value ', this.child.getFirstData());
    console.log('last value ', this.child.getLastData());

  }

  getValues(): void {
    // some operations heer
  }
}

我无法从 child 获取数据。

我的目标是在 child 中的按钮单击事件发生后调用方法后接收这些数据。接收后,我需要调用 parent 组件中的 getValues() 方法。

我怎样才能做到这一点?

示例 - Output decorator

子组件:

export class ChildComponent implements OnInit, AfterViewInit {
  firstItem: number;
  lastItem: number;

  @Output() firstItemChanged = new EventEmitter<number>();
  @Output() lastItemChanged = new EventEmitter<number>();

  constructor() {
  }

  ngOnInit() {
  }

  ngAfterViewInit(): void {
  }

  getFirstData() {
    this.firstItem = 1;
    this.firstItemChanged.emit(this.firstItem);
  }

  getLastData() {
    this.lastItem= 10;
    this.firstItemChanged.emit(this.lastItem);
  }

}

父组件html:

    <child-component (firstItemChanged)="handleFirstItemChanged($event)" (lastItemChanged)="handleLastItemChanged($event)"></child-component>

父组件:

export class ParentComponent {

  handleFirstItemChanged(value: number): void {
    // handle event
  }

  handleLastItemChanged(value: number): void {
    // handle event
  }
}

示例 - BehaviorSubject

子组件:

interface State {
  firstItem: number;
  lastItem: number;
}

export class ChildComponent {

  state = new BehaviorSubject<State>({
    firstItem: 0,
    lastItem: 0
  });

  constructor() { }

  firstButtonClicked() {
    const newState = this.state.value;
    newState.firstItem = 1;
    this.state.next(newState);
  }

  lastButtonClicked() {
    const newState = this.state.value;
    newState.lastItem = 1;
    this.state.next(newState);
  }
}

父组件:

export class ParentComponent implements AfterViewInit {

  @ViewChild(ChildComponent, {static: true}) child: ChildComponent;

  ngAfterViewInit(): void {
    this.child.state.subscribe(state => {
      // handle
    });
  }
}