Angular 子组件不会立即更新

Posted

技术标签:

【中文标题】Angular 子组件不会立即更新【英文标题】:Angular Child Component is not being updated inmediatly 【发布时间】:2019-02-26 02:39:39 【问题描述】:

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

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

    我的父母正在使用输入绑定向我的孩子分享信息 按钮触发更新信息的功能 父母通过@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 稍等一下,一切正常。

我的问题:

    从父级向子级发送数据并在子级中直接使用的最佳方式是什么? 我做错了什么?

非常感谢您的帮助,谢谢

【问题讨论】:

它适用于我的 Chrome。见this stackblitz。 @ConnorsFan ,请您参加控制台吗?第一次点击按钮出现“Nothing yet”.....第二次不同 你是对的。如果您在设置值后调用ChangeDetectorRef.detectChanges(),则它可以工作。见the stackblitz。 @ConnorsFan 感谢您的快速回复。但是使用 detectChanges 不会对性能不利吗? 另一种方法是在按钮事件处理程序中调用的子组件方法中设置值。 【参考方案1】:

实际上一切正常。您遇到的情况如下。

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

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

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

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

ngOnChanges(): void 
  console.log('onChanges', this.data);

【讨论】:

【参考方案2】:

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

Example Stackblitz

【讨论】:

谢谢,但我真正期望的不是在控制台上写任何组件,而是希望我的 ChildComponent 写入最近更改的值 Updated Stackblitz - 这个? 是另一种很好的方式....尽管在这种情况下不需要输入绑定....谢谢 我认为,理想情况下,哑组件不会包含像写入控制台这样的逻辑。相反,子组件应该向处理所述逻辑的父组件发出事件。但是,您可能会遇到另一种情况。

以上是关于Angular 子组件不会立即更新的主要内容,如果未能解决你的问题,请参考以下文章

Angular ViewChildren 不会立即看到来自 ngFor 的所有孩子

从Angular 2中的子组件更新父组件属性

将值传递给子组件Angular 7

子组件中的 Angular 2 ngModel 更新父组件属性

从Angular 5中的子组件更新父布尔值

Angular 6 Change detection - 如何设置子组件?