0

我正在学习 Angular 6,我认为我做得对,但我正面临“问题怀疑”

我有一个父母和一个孩子:

  1. 我的父母正在使用输入绑定向我的孩子分享信息
  2. 一个按钮触发更新信息的功能
  3. Inmediatly,父母通过@ViewChild 调用子函数

可以在这里找到Stackblitz

我的父组件看起来像:

html:

This is the parent
<child [data]="my_data"></child>
<button (click)="fireAll()">Fire All!</button>

打字稿:

export class AppComponent  {
  @ViewChild(ChildComponent) childComp: ChildComponent;
  my_data = 'Nothing yet';

  public fireAll(){
    this.my_data = "I want to show this info in console";
    this.childComp.writeToConsole();
    //setTimeout(()=>this.childComp.writeToConsole(), 500); //This works well
  }

}

孩子:

export class ChildComponent  {
  @Input() data: string;

  writeToConsole(){
    console.log(this.data);
  }
}

问题是:第一次单击按钮时,我希望在控制台中看到“我想在控制台中显示此信息”,而不是收到“还没有”。但是如果我再次点击它,就会达到预期的结果。我想父级将数据传递给子级之间存在延迟,因为如果我使用 setTimeout 稍等一下,一切正常。

我的问题:

  1. 将数据从父母发送到孩子并在孩子中直接使用的最佳方式是什么?
  2. 我究竟做错了什么?

非常感谢您的帮助,谢谢

4

2 回答 2

3

实际上一切正常。你所经历的事情如下。

  1. 你按下按钮
  2. 你更新my_data
  3. 你调用孩子的writeToConsole方法。
  4. 此时,变更检测仍在评估所有组件
  5. 孩子还没有更新,所以你仍然得到旧数据
  6. 变更检测完成,新数据通过

在您的设置中,控制台日志总是比您期望的要落后一步。您在更改检测可以完成工作之前调用该方法。在您引入延迟 (setTimeout) 的那一刻,更改检测将在您调用该方法之前执行。这就是为什么它在你眼中“起作用”。

总之,一切正常。父母不应该调用孩子的方法。它应该只向孩子提供数据。

如果您想尽快使用新值,您应该实施OnChanges. 它会在新数据进入组件时通知您。

ngOnChanges(): void {
  console.log('onChanges', this.data);
}
于 2018-09-21T18:49:27.177 回答
0

我已经更新了你的 stackblitz。第一次单击时,我首先将“我想在控制台中显示此信息”打印到控制台。

示例 Stackblitz

于 2018-09-21T16:50:57.150 回答