从服务器获取数据不会触发子组件中的更改检测 [重复]

Posted

技术标签:

【中文标题】从服务器获取数据不会触发子组件中的更改检测 [重复]【英文标题】:Fetching data from server doesn't trigger change detection in child component [duplicate] 【发布时间】:2019-11-30 03:47:04 【问题描述】:

我正在开发一些应用程序,其中有一个具有某些属性的对象,并且当我发出 http 请求时,会向该对象添加新属性。

    this.user = 
      id: 1,
      name: 'John'
    

    this.http.get('https://api.chucknorris.io/jokes/random')
      .subscribe(joke => this.user.joke = joke);

问题是在发出请求时没有执行更改检测(this 文章指出,只要我不修改更改检测策略就应该执行它)。

因此,ngOnChanges 不会在我传递用户对象的子组件中被调用,并且当值从服务器到达时我正在做一些复杂的事情。

我附上了一个简化的stackblitz 演示。

注意:我知道当新数据到达时我可以传递该对象的副本,但我认为这应该是更好的方法。

【问题讨论】:

stackblitz.com/edit/angular-th9oze?file=src/app/… @AJT_82 好答案。或许加一句解释为什么代码是正确的? @AJT_82 在您告诉我为什么会这样之前,请不要将我的问题标记为重复。我给您提供了一篇文章的参考,该文章指出“重复”问题的答案不正确,除非您将更改检测策略更改为OnPush。如果我误解了这篇文章,请告诉我。顺便说一句,我也在考虑我的问题中的更改检测策略,所以我认为这是不将问题标记为重复的另一个原因 如重复状态:If you modify the content of an object, Angular won't recognize. 这只是一个事实。如果您要使用原始值,则更改检测会对此进行检测,但这里我们正在处理一个对象,并且除非参考更改,否则角度不会获取更改。同样,如果这是一个数组,并且您要修改数组中的一个对象,则 angular 不会接受。 @AJT_82 我读了这个问题,我明白了。但是this 文章说whenever some asynchronous operation has been performed, our application state might have changed。所以肯定有人错了(回答 *** 问题的人或写这篇文章的人)。 IMO,写***问题的人错了,所以我不敢相信If you modify the content of an object, Angular won't recognize。请给我一份正式的参考资料。 【参考方案1】:

除非检测到新的引用,否则不会触发角度变化检测。

如果你用 self 和 new 属性覆盖现有用户,angular 将检测到新的引用并更新。

 this.http.get('https://api.chucknorris.io/jokes/random')
      .subscribe(joke => this.user = ...this.user, joke;

【讨论】:

为什么投反对票? 因为我已经提到“注意:我知道我可以在新数据到达时传递该对象的副本,但我认为这应该是更好的方法”。即便如此,@AJT_82 已经给了我这个答案 @MTZ 好吧,老实说,我没有注意到这一点。我仍然认为这是最好的方法,除非你真的需要相同的参考。你试过用 changeDetectorRef 吗? 是的。我试过了。

以上是关于从服务器获取数据不会触发子组件中的更改检测 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

React 功能组件状态变化不会触发子组件重新读取其 props

从路由加载子组件时从父组件触发子组件方法

$emit 不会触发子事件

vue父组件点击触发子组件事件的实例讲解

JavaScript | ReactJS:父状态更改不触发子道具更新

VueJS - 触发子函数