Angular 可观察到的错误不会刷新界面 ChangeDetectionStrategy.OnPush
Angular observable on error does not refresh interface with ChangeDetectionStrategy.OnPush
我有一个使用服务提交一些数据的组件。
此组件使用 ChangeDetectionStrategy.OnPush
,但发生了一些奇怪的事情:
请求成功时:调用next
回调,formStatus
变为'success'和界面刷新 有了这个改变。
当请求失败时,调用error
回调,formStatus
变为'error'但接口不刷新此更改。
据我了解,界面不应刷新,因为我使用 ChangeDetectionStrategy.OnPush
并且我正在更改基本类型字符串变量。
那么,¿为什么在 next
中触发变化检测?
组件
当服务发生错误时,我想在错误回调中接收它。
submit() {
this.formStatus = 'sending';
this._service.create(data).subscribe({
next: () => {
this.formStatus = 'success';
// interface refreshes
},
error: () => {
this.formStatus = 'error';
// interface does not refresh
console.log(this.formStatus); // prints 'error'
},
});
}
<div *ngIf="formStatus === 'success'">
...
</div>
服务
调用 API 并使用 errorUtil.handle
捕获错误,这会引发 rxjs 错误(因为我想 return Observable.error)。
create(requestData: Data): Observable<Data> {
return this._http
.post<HttpResponse<CreateResponse>>(
MY_API.createUrl,
JSON.stringify(requestData)
)
.pipe(
catchError(this._errorUtil.handle()),
map(data => this.onSuccessCreate(requestData, data))
);
}
错误处理程序
handle<T>(): (error: HttpErrorResponse, caught?: Observable<T>) => Observable<T> {
return (error: HttpErrorResponse, caught?: Observable<T>) => {
return throwError();
};
}
我试过将 return throwError();
更改为 throw throwError();
但行为是一样的。
这是一个奇怪的行为,我仍然不明白为什么在调用 next 时,界面会更新。应该也不更新了。
正确的方法是使用 stream 来监听表单状态的变化。
组件
type FormStatus = 'clean' | 'sending' | 'success' | 'error';
// ...
private _formStatus$: BehaviorSubject<FormStatus> = new BehaviorSubject<FormStatus>('clean');
set formStatus(status: FormStatus) {
this._formStatus$.next(status);
}
get formStatus$(): Observable<FormStatus> {
return this._formStatus$.pipe(
shareReplay({ refCount: true, bufferSize: 1 })
);
}
<div *ngIf="(formStatus$ | async) !== 'error'">
...
</div>
我有一个使用服务提交一些数据的组件。
此组件使用 ChangeDetectionStrategy.OnPush
,但发生了一些奇怪的事情:
请求成功时:调用
next
回调,formStatus
变为'success'和界面刷新 有了这个改变。当请求失败时,调用
error
回调,formStatus
变为'error'但接口不刷新此更改。
据我了解,界面不应刷新,因为我使用 ChangeDetectionStrategy.OnPush
并且我正在更改基本类型字符串变量。
那么,¿为什么在 next
中触发变化检测?
组件
当服务发生错误时,我想在错误回调中接收它。
submit() {
this.formStatus = 'sending';
this._service.create(data).subscribe({
next: () => {
this.formStatus = 'success';
// interface refreshes
},
error: () => {
this.formStatus = 'error';
// interface does not refresh
console.log(this.formStatus); // prints 'error'
},
});
}
<div *ngIf="formStatus === 'success'">
...
</div>
服务
调用 API 并使用 errorUtil.handle
捕获错误,这会引发 rxjs 错误(因为我想 return Observable.error)。
create(requestData: Data): Observable<Data> {
return this._http
.post<HttpResponse<CreateResponse>>(
MY_API.createUrl,
JSON.stringify(requestData)
)
.pipe(
catchError(this._errorUtil.handle()),
map(data => this.onSuccessCreate(requestData, data))
);
}
错误处理程序
handle<T>(): (error: HttpErrorResponse, caught?: Observable<T>) => Observable<T> {
return (error: HttpErrorResponse, caught?: Observable<T>) => {
return throwError();
};
}
我试过将 return throwError();
更改为 throw throwError();
但行为是一样的。
这是一个奇怪的行为,我仍然不明白为什么在调用 next 时,界面会更新。应该也不更新了。
正确的方法是使用 stream 来监听表单状态的变化。
组件
type FormStatus = 'clean' | 'sending' | 'success' | 'error';
// ...
private _formStatus$: BehaviorSubject<FormStatus> = new BehaviorSubject<FormStatus>('clean');
set formStatus(status: FormStatus) {
this._formStatus$.next(status);
}
get formStatus$(): Observable<FormStatus> {
return this._formStatus$.pipe(
shareReplay({ refCount: true, bufferSize: 1 })
);
}
<div *ngIf="(formStatus$ | async) !== 'error'">
...
</div>