首页 > 解决方案 > *ngFor 行为主题 | 异步不更新

问题描述

我对 BehaviorSubject 和异步管道有疑问。它没有向我显示 .next() 之后的所有 BehaviorSubject 项目。它只显示“prova”项目。我在拦截器中记录了错误$并且我还有其他项目。为什么它不显示页面中的所有项目?谢谢

模板

<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);

        }));

    }

}

标签: angularbehaviorsubject

解决方案


对,因为值就是你传递给.next. 如果您想收集所有错误,则需要将代码更改为类似

errors$.next([...errors$.value, newError]);

一个可能的解决方案是创建一个令牌并共享BehaviourSubject.

providers: [
  {
    provide: 'errors',
    useValue: new BehaviorSubject(['prova']),
  },
],

然后在您的组件代码中而不是注入ErrorInterceptorinject @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>

推荐阅读