【发布时间】:2018-12-03 14:51:12
【问题描述】:
我有一个用户库,用于我组织中的多个 Angular 应用程序。作为重构/新版本,我们希望转向基于状态的服务,其接口类似于:
export interface UserService {
user: Observable<User>
getProfile(url: string): Observable<User>
updateProfile(url: string): Observable<User>
}
这样,消费者可以将组件绑定到UserService.user,知道数据将始终是最新的,并在按钮或后台活动等中调用get/update函数。
澄清:用户库旨在用于使用 ngRx 的应用程序,以及那些不想要如此繁重但仍需要基于 observable 的用户绑定的应用程序。
所以我将这样的函数连接起来(略有不同):
public getProfile(url: string): Observable<User> {
const obs = this._http.get<User>(url);
obs.subscribe(profile => this.setProfile(profile));
return obs;
}
其中setProfile 更新UserService.user 以只读方式返回的内部订阅。
有一次我的消费者应用程序使用ngRx 进行其余的状态管理。在使用我的图书馆时,我们发现了一些奇怪的现象:
当包裹在
ngRx效果中时,有时任何使用 Angular 的HttpClient的函数都会被多次调用。为了解决这个问题,我使用HttpClient的任何函数都以.publishLast().refCount()结尾,以确保只进行一次HTTP 调用。如果调用失败,消费者无法捕获异常。例如,
this.authService.getProfile().catch(error => alert(error))永远不会被调用。为了解决这个问题,我现在正在修改他们订阅的函数:obs.subscribe(profile => this.setProfile(profile), error => Observable.throw(error));
在 Angular 中实现“状态存储”服务时这是正常行为吗?
编辑:示例 ngRx 效果(请注意,这是真正的实现,我上面发布的内容是从我们的实际实现中简化的):
public BiographyUpdate: Observable<any> = this._actions.pipe(
ofType(AuthActionTypes.BIOGRAPHY_UPDATE),
map((action: BiographyUpdate) => action.payload),
switchMap(bio => this._auth.update(`${Environment.Endpoints.Users}/users/sync/biography`, action)
.map(profile => new BiographyUpdateSuccess(profile.biography))
.catch(error => {
console.log("AM I BEING HIT?");
return Observable.of(new BiographyUpdateFailure(error.toString()))
})
)
);
【问题讨论】:
-
可以分享ngrx效果代码吗?
标签: angular rxjs ngrx angular-httpclient