简体   繁体   English

创建Angular4“正在加载”屏幕:ExpressionChangedAfterItHaHasBeenCheckedError

[英]Creating Angular4 'Loading' Screen: ExpressionChangedAfterItHasBeenCheckedError

I have created a custom loading screen where an Angular component (fullscreen DIV with SVG animation) is displayed above all other HTML. 我创建了一个自定义加载屏幕,其中在所有其他HTML上方显示了一个Angular组件(带有SVG动画的全屏DIV)。 My issue is with calling the loading screen. 我的问题是调用加载屏幕。 At the moment, I have a boolean in a global service with an "_isLoading" variable. 目前,我在全局服务中有一个带有“ _isLoading”变量的布尔值。 When set to true, the loading screen is displayed (and vice versa), as seen below: 设置为true时,将显示加载屏幕(反之亦然),如下所示:

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

By default, the '_isLoading' variable is set to 'true' to display the loading screen upon initial application load. 默认情况下,“ _ isLoading”变量设置为“ true”,以在初始应用程序加载时显示加载屏幕。 The 'childcomponent' sets the '_isLoading' variable to 'false' once 'ngAfterViewInit' has been called, as the HTML from the child component has then loaded. 一旦调用了“ ngAfterViewInit”,“子组件”会将“ _isLoading”变量设置为“假”,因为子组件的HTML随后已被加载。 This throws an 'ExpressionChangedAfterItHasBeenCheckedError'. 这将引发“ ExpressionChangedAfterItHasBeenCheckedError”。 I've read the In-Depth Blog Post on the error, and I understand that this problem is occurring due to the child component changing a variable that the digest cycle in the parent component just checked. 我已经阅读了有关该错误的深入博客文章 ,并且我了解到此问题的发生是由于子组件更改了刚刚检查了父组件中摘要循环的变量。 What I don't know is how to get around this. 我不知道该如何解决。 I assume others have created Loading Screens before... What is the standard / norm for doing this? 我假设其他人之前已经创建了“加载屏幕” ...执行此操作的标准/规范是什么?

ngAfterViewInit is exactly what gives you trouble. ngAfterViewInit正是给您带来麻烦的原因。 It is called after view has been updated with all values bound to it. 视图绑定了所有值之后 ,将对其进行调用。 So, at this moment you really should not change any data used in bindings. 因此,目前您真的不应该更改绑定中使用的任何数据。 This also means that avoiding this error is pretty simple: all you need to do is just to wait for another change detection cycle. 这也意味着避免该错误非常简单:您需要做的就是等待另一个变更检测周期。 Simplest solution is to set timeout: 最简单的解决方案是设置超时:

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

But actually, I would not implement setting of this flag from two different places. 但是实际上,我不会在两个不同的地方实现此标志的设置。 The reason being is that the component starting some operation assumes responsibility for updating that operation's status. 原因是启动某个操作的组件承担更新该操作状态的责任。 Otherwise you will end up guessing "which component just killed this request?". 否则,您将最终猜测“哪个组件刚刚终止了此请求?”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM