*ngFor 行为主题 |异步不更新
*ngFor behaviourSubject | async don't update
我对 BehaviorSubject 和异步管道有疑问。它没有向我显示 .next() 之后的 BehaviorSubject 的所有项目。它只显示 'prova' 项。我在拦截器中记录了 errors$ 并且我还有其他 items.Why 它没有向我显示页面中的所有项目?谢谢
模板
<div class="alerts">
<div class="alert" *ngFor="let error of (errorInterceptor.errors$ | async) ">
{{error}}
</div>
</div>
错误拦截器
@Injectable({ providedIn: 'root' })
export class ErrorInterceptor implements HttpInterceptor {
errors$ = new BehaviorSubject<string[]>(['prova']);
constructor() {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
if (err.status >= 400 && err.status < 500) {
console.error('error-interceptor:error status=' + err.status + ' message=' + err.message + ' msg='+err.msg);
const errors = [...this.errors$.value];
errors.push(err.status);
this.errors$.next(errors);
console.table(this.errors$.value);
} else {
console.error('error-interceptor:err=' + err.error + ' statusText=' + err.statusText + ' status:' + err.status);
}
const error = err.error.msg || err.statusText;
return throwError(error);
}));
}
}
正确,因为值是您传递给 .next
的值。
如果您想收集所有错误,您需要将代码更改为
errors$.next([...errors$.value, newError]);
一个可能的解决方案是创建一个令牌并共享 BehaviourSubject
。
providers: [
{
provide: 'errors',
useValue: new BehaviorSubject(['prova']),
},
],
然后在你的组件代码中而不是注入 ErrorInterceptor
注入 @Inject('errors') public readonly errors$: Observable<string[]>
.
并更新拦截器以执行相同的操作。
constructor(@Inject('errors') protected readonly errors$: BehaviorSubject<string[]>) {}
// ....
this.errors$.next(errors);
之后您可以在模板中使用
<div class="alerts">
<div class="alert" *ngFor="let error of (errors$ | async) ">
{{error}}
</div>
</div>
我对 BehaviorSubject 和异步管道有疑问。它没有向我显示 .next() 之后的 BehaviorSubject 的所有项目。它只显示 'prova' 项。我在拦截器中记录了 errors$ 并且我还有其他 items.Why 它没有向我显示页面中的所有项目?谢谢
模板
<div class="alerts">
<div class="alert" *ngFor="let error of (errorInterceptor.errors$ | async) ">
{{error}}
</div>
</div>
错误拦截器
@Injectable({ providedIn: 'root' })
export class ErrorInterceptor implements HttpInterceptor {
errors$ = new BehaviorSubject<string[]>(['prova']);
constructor() {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
if (err.status >= 400 && err.status < 500) {
console.error('error-interceptor:error status=' + err.status + ' message=' + err.message + ' msg='+err.msg);
const errors = [...this.errors$.value];
errors.push(err.status);
this.errors$.next(errors);
console.table(this.errors$.value);
} else {
console.error('error-interceptor:err=' + err.error + ' statusText=' + err.statusText + ' status:' + err.status);
}
const error = err.error.msg || err.statusText;
return throwError(error);
}));
}
}
正确,因为值是您传递给 .next
的值。
如果您想收集所有错误,您需要将代码更改为
errors$.next([...errors$.value, newError]);
一个可能的解决方案是创建一个令牌并共享 BehaviourSubject
。
providers: [
{
provide: 'errors',
useValue: new BehaviorSubject(['prova']),
},
],
然后在你的组件代码中而不是注入 ErrorInterceptor
注入 @Inject('errors') public readonly errors$: Observable<string[]>
.
并更新拦截器以执行相同的操作。
constructor(@Inject('errors') protected readonly errors$: BehaviorSubject<string[]>) {}
// ....
this.errors$.next(errors);
之后您可以在模板中使用
<div class="alerts">
<div class="alert" *ngFor="let error of (errors$ | async) ">
{{error}}
</div>
</div>