2017-10-19 69 views
1

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

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

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

+0

我提出了一个类似的问题的解决方案:https://stackoverflow.com/questions/46837438/angular2-expressionchangedafterithasbeencheckederror –

+0

我从来没有遇到过这个错误,因为我反过来这样做。我在开始时将其设置为false,然后在加载函数时(例如订阅observable并检索数据时)将其标记为true,然后在完成时将其设置为false。 –

+0

阅读文章[你需要知道的关于'ExpressionChangedAfterItHasBeenCheckedError'错误的所有信息](https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbabecheckederror-error-e3fd9ce7dbb4) –

回答

2

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

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

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

+0

我打算给这个方法一个镜头,但你是对的。我将重新设计它,以便只在相同的组件内切换标志。 – fila

+0

这解决了我的问题。这是因为我在AfterViewInit中调用它。我已经改变了现在我切换HTML的方式,并且只在同一个组件中打开/关闭它......再也没有问题了。感谢Alexander! – fila