【问题标题】:Creating Angular4 'Loading' Screen: ExpressionChangedAfterItHasBeenCheckedError创建 Angular4“加载”屏幕:ExpressionChangedAfterItHasBeenCheckedError
【发布时间】:2017-10-19 21:38:06
【问题描述】:

我创建了一个自定义加载屏幕,其中一个 Angular 组件(带有 SVG 动画的全屏 DIV)显示在所有其他 HTML 之上。我的问题是调用加载屏幕。目前,我在全局服务中有一个带有“_isLoading”变量的布尔值。设置为 true 时,会显示加载屏幕(反之亦然),如下所示:

<app-loading-screen *ngIf="dataService._isLoading"></app-loading-screen>
<div id="pageWrapper">
    <app-childcomponent></app-childcomponent>
</div>

默认情况下,“_isLoading”变量设置为“true”以在初始应用程序加载时显示加载屏幕。一旦调用了“ngAfterViewInit”,“childcomponent”就会将“_isLoading”变量设置为“false”,因为随后加载了来自子组件的HTML。这会引发“ExpressionChangedAfterItHasBeenCheckedError”。我已经阅读了关于错误的In-Depth Blog Post,并且我知道这个问题是由于子组件更改了父组件中的摘要循环刚刚检查的变量而发生的。我不知道如何解决这个问题。我假设其他人之前已经创建了加载屏幕......这样做的标准/规范是什么?

【问题讨论】:

  • 我针对类似问题提出了解决方案:stackoverflow.com/questions/46837438/…
  • 我从来没有遇到过这个错误,因为我是反过来的。我在开始时将其设置为 false,然后在加载函数时将其标记为 true(例如,当它订阅 observable 并检索数据时),然后在完成时将其设置回 false。
  • @AngularInDepth.com - 我已经阅读了它,我什至已将原始问题中的链接发布到 Stack Overflow。但这并不能回答我的问题 - 我在问在设计自定义加载屏幕时可以/应该使用什么方法来解决这个问题。

标签: angular


【解决方案1】:

ngAfterViewInit 正是给您带来麻烦的原因。它被称为 视图已更新所有绑定到它的值。因此,此时您真的不应该更改绑定中使用的任何数据。这也意味着避免此错误非常简单:您需要做的只是等待另一个更改检测周期。最简单的解决方案是设置超时:

ngAfterViewInit() {
    setTimeout(() => {
        dataservice._isLoading = false;
    });
}

但实际上,我不会从两个不同的地方设置此标志。原因是启动某些操作的组件承担了更新该操作状态的责任。否则你最终会猜测“哪个组件刚刚杀死了这个请求?”。

【讨论】:

  • 我打算试试这个方法,但你是对的。我将重新设计它,以便仅在同一组件内切换标志。
  • 这解决了我的问题。这是因为我在 AfterViewInit 中调用它。我现在改变了切换 HTML 的方式,并且只在同一个组件中打开/关闭它......不再有问题了。谢谢亚历山大!
猜你喜欢
  • 2018-05-29
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 2016-04-16
  • 1970-01-01
  • 2017-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多