【问题标题】:When fetching data with Observable, need to use detector.detectChanges Angular v6+使用 Observable 获取数据时,需要使用detector.detectChanges Angular v6+
【发布时间】:2020-01-21 00:03:23
【问题描述】:

我的 Angular 项目中有一个奇怪的错误。当我使用模拟 API 从本地数据中获取数据时,一切正常,但是当我切换到在线 API 并使用 Observable 订阅方法获取数据时,我的角度模板视图中的数据不会更新。只有当我调用detector.detectChanges() 方法时才会更新。

简而言之,在使用在线 API 时,双向数据绑定仅在我调用 detectChanges 时才有效。

例如想象下面的场景:

 data = [some data here...]
 getData(): Observable<any> {
    return of(this.data);
}

当我在.ts 文件中调用此方法并使用它获取数据时,角度模板将自动更新。但是当我切换到下面的代码时:

getData(): Observable<any> {
    let url = `${this.API_URL}/fetchData/`;
    return this.http.get(url);
}

并在我的 Angular .ts 文件中获取数据,如下所示:

this.myService.getData().subscribe(result => {
    this.myData = result;
    // this.detector.detectChanges();
})

myData 变量不会在角度模板中更新,除非我取消注释 // this.detector.detectChanges() 方法。

detectChanges是从下面的angular库中导入的:

private detector: ChangeDetectorRef,

谁能帮我克服这个错误?这真的很烦人,我的代码现在到处都有很多detectChanges,就在任何需要双向数据绑定的代码之后!

提前致谢

更新

我的 .html 文件

 <table class="table table-bordered table-striped table-responsive"
                           style="display: inline-table;">
                        <thead>
                        <tr style="left: 0;">
                            <th><span>test</span></th>
                        </tr>
                        </thead>
                        <tbody>
                            <tr style="left: 0;" *ngFor="let d of myData">
                               <td>{{d.test}}</td>
                            </tr>
                        </tbody>
                    </table>

【问题讨论】:

  • 为什么不直接将this.myService.getData()设置为this.myData,使其成为Observable,并在模板中使用async管道(例如myData | async)?
  • 你能解释更多细节,也许在答案部分。我真的很感激任何帮助;)
  • 你能先给我们看看你的模板(.html)吗?
  • 这是正常的 html。我更新了它的一部分。
  • 检查 changeDetection: ChangeDetectionStrategy.OnPush 在你的 @Component 装饰器配置中。删除它,如果您希望 angular CD 在发生异步事件后为您进行脏检查。

标签: angular rxjs observable two-way-binding


【解决方案1】:

与我不喜欢在 HTML 中执行异步操作的 cmets 不同,我按照您在上面编写的代码执行此操作。我的问题是您在组件上的ChangeDetectionStrategyset 是什么。其中一些不会自动通知更改并更新 UI(这可以解释您的问题)。

这是因为,在模板的app.component.ts 中,它使用了changeDetectionStrategy.onPush,所以基本上每当在角度上下文中发生任何事情时,我都应该使用像detector.detectChanges() 这样的命令。 只需使用changeDetectionStrategy.Default 一切都会正常,角度双向绑定也可以正常工作。

【讨论】:

  • 是的,我认为他将 Strategy 设置为 OnPush。
  • 我使用的是 metronic 开源模板。好像是在ChangeDetectionStrategy.onPush。现在我将其更改为 Default 一切似乎都正常。我想只要改变我所有的问题都解决了。我说的对吗?
  • 当你使用 OnPush 检测变化是由输入变化触发的,事件触发,使用 |模板中的异步或手动调用检测更改或 markForCheck,使用 OnPush 您将获得最佳性能,但您必须习惯在编写代码时牢记这 4 件事
  • 谢谢。问题解决欣赏。我也更新了你的答案
猜你喜欢
  • 1970-01-01
  • 2018-07-22
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 2022-01-27
  • 2020-11-05
  • 2021-03-18
  • 2023-04-09
相关资源
最近更新 更多