Sha*_*iel 7 angular-http-interceptors angular
我有一个简单的Angular 5应用程序,它带有一个HttpInterceptor,它在发出请求时通知服务。组件可以订阅此服务以获取此信息。
此处有错误的完整示例 => https://stackblitz.com/edit/angular-5b86se
在我的AppComponent 中,当我的子组件 ( HelloComponent ) 中发出请求时,我想显示一个加载指示器。
import { Component } from '@angular/core';
import { LoadingIndicatorService } from './loading-indicator.service';
@Component({
selector: 'my-app',
template: `<div *ngIf="loading" style="color:red">pretend this is loading indicator</div>
<hello name="{{ name }}"></hello>`
})
export class AppComponent {
name = 'Angular 5';
loading: boolean = false;
constructor(private loadingIndicatorService: LoadingIndicatorService) {
loadingIndicatorService
.onLoadingChanged
.subscribe(isLoading => this.loading = isLoading);
}
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
错误:ExpressionChangedAfterItHasBeenCheckedError:检查后表达式已更改。以前的值:'假'。当前值:“真”。
如果我是正确的,当子组件更改父组件中的值时会出现此错误。
但是我的子组件(HelloComponent)只执行 HttpGet 并且HttpInterceptor正在通过具有可观察的服务更改父组件(AppComponent)。
在这里更改服务不应该是正确的解决方案吗?有人可以解释为什么这不起作用吗?
它会引发错误,因为您的变量加载在onLoadingChanged调用时会更新。这意味着您的初始值已更改。
我建议您阅读更多有关here
对此的一般解决方法是,
constructor(private loadingIndicatorService: LoadingIndicatorService,private ref: ChangeDetectorRef) {
loadingIndicatorService.onLoadingChanged.subscribe(isLoading => {
this.loading = isLoading
this.ref.detectChanges();
});
}
Run Code Online (Sandbox Code Playgroud)
ExpressionChangedAfterItHasBeenCheckedError当表达式在一个更改检测生命周期内更改多次时,会抛出该异常(在开发人员模式下)。那么在你的例子中它是如何变化的呢?
生命周期#1:
loading: boolean = false;在构造函数期间AppComponentonInit. 然后,这会触发更新可观察值的拦截器。生命周期#2(在开发模式下,检查所有值是否稳定/仍然相同):
loading现在是true因为对 observable 的订阅改变了值,该值与之前的值不同loading = false,所以 Angular 抛出错误。为了缓解该问题,您可以:
onInit构造函数移至构造函数。缺点:不建议在构造函数中做一些事情setTimeout(() => myObservable.next(...));。缺点:很丑。但是,如果您希望多个客户端订阅您的 observable,这可能会给您带来最少的麻烦,因为您不必在任何地方都包含 cdr。老实说,这些解决方案都不是特别漂亮。
请注意,async管道与另一个答案中建议的问题无关。
| 归档时间: |
|
| 查看次数: |
6325 次 |
| 最近记录: |