【发布时间】:2021-03-10 14:11:01
【问题描述】:
我有一个 Angular 应用程序,使用 AngularFire、NgRx 和 Cloud Firestore 作为数据库,我在其中启用了 @ 987654321@.
我的问题是,当我在离线时更改文档时,效果函数不会触发成功操作,因为 Firestore 承诺在离线时不会被解析,而只有在请求到达服务器后才会解析。
目前,我一直在努力寻找一种在离线时使用本地数据更新商店的好方法。
一个想法可能是在加载数据之前检查fromCache 标志,这样如果 fromCache 为真(即我们离线)我可以从本地数据库而不是存储加载数据,但看起来对我来说就像一个肮脏的解决方法。
效果
//--- Effect triggered to load document in the home page ----
firstSet$ = createEffect(() => {
return this.actions$.pipe(
ofType(PlacesActions.loadFirstPlaces),
switchMap(() => {
return this.placeService.getFirstSet().pipe(
map((places) => {
return PlacesActions.loadFirstPlacesSuccess({ places });
}),
catchError((error) => of(PlacesActions.loadFirstPlacesFailure({ error }))),
takeUntil(this.subService.unsubscribe$)
);
})
);
});
//--- Effect triggered when a document is updated ----
updatePlace$ = createEffect(() => {
return this.actions$.pipe(
ofType(PlacesActions.updatePlace),
concatMap((action) => {
// ----- Below the NEW code, without promise ----
try {
this.placeService.savePlace(action.place);
this.router.navigate(['/home']);
return of(PlacesActions.updatePlaceSuccess({ place: action.place }));
}
catch(error) {
return of(PlacesActions.updatePlaceFailure({ error }))
}
/*
// ----- Below the old code ----
return from(this.placeService.savePlace(action.place))
.pipe(
map((place: Place) => {
this.router.navigate(['/home']);
return PlacesActions.updatePlaceSuccess({ place });
}),
catchError((error) => of(PlacesActions.updatePlaceFailure({ error })))
);
*/
})
);
});
数据库服务
savePlace(place): void {
this.firestoreRef.doc<Place>(`places/${place.id}`).update(place);
}
/* Old version of savePlace using Promise for the Update
async savePlace(place): Promise<void> {
return await this.firestoreRef.doc<Place>(`places/${place.id}`).update(place);
}
*/
loadFirstPlaces(limit: number = 9,
orderBy: OrderModel = { propName: 'modifiedOn', order: 'desc' }){
const query = (ref: CollectionReference) =>
ref.orderBy(orderBy.propName, orderBy.order)
.limit(limit);
return this.firestoreRef.collection<Place>('Places', query)
.valueChanges()
.pipe(shareReplay(1));
}
首页组件
ngOnInit(): void {
// Set the data from the store, if available there
this.places$ = this.store.select(getAllPlaces).pipe(
tap((data) => {
this.places = data;
})
);
/*Dispatch load action to load data from the server or local cache.
If I use the PROMISE approach for the update method,
the data coming from the local cache has the old data.
The edits done while offline are not provided.*/
this.store.dispatch(loadFirstPlaces());
}
【问题讨论】:
标签: javascript firebase google-cloud-firestore ngrx angularfire2