如何使用效果组合ngrx实体(作为前端调用的结果定期返回)



[angular][javascript][ngrx/intities][ngrx/effects][rxjs]

以下是我的效果。这用于从后端获取数据。

//effects.ts
loadCourierItems$ = createEffect(() =>
this.actions$.pipe(
ofType(CourierItemActions.loadCourierItems),
mergeMap(action =>
this.defaultService.getCourierItems(
).pipe(
map(CourierItems => CourierItemActions.loadCourierItemsSuccess({ CourierItems })),
catchError(error =>
of(CourierItemActions.loadCourierItemsFailure({ error }))
)
)
)
)
)

以下是我的选择

//selector.ts
export const selectCourierItemState = createFeatureSelector<CourierItemState>(
CourierItemsFeatureKey
);
export const selectCourierItems = createSelector(selectCourierItemState, selectAll);

这是我第一次调度操作以获取数据的组件:

//app.component.ts
constructor(private store: Store<CourierItemsState>) {
this.store.dispatch(loadCourierItems())
}
ngOnInit() {
this.courierItems$ = this.store.pipe(select(selectCourierItems))
}
//template.html

<div *ngFor="let item of courierItems$ | async as courier>
<p>{{courier.name}}</p>
<p>{{courier.loc_cur}}</p>
etc...
</div>
...

我该怎么做?

我想实现的是,我想每1秒发出一个新的请求,效果是(后端将发回一个由10个项目组成的数组(我想将这些项目组合到一个实体集合中。

更新

loadCourierItems$ = createEffect(() =>
this.actions$.pipe(
ofType(CourierItemActions.loadCourierItems),
exhaustMap(action => interval(1000).pipe(
takeUntil(this.actions$.pipe(ofType(CourierItemActions.stopCourierItems))),
exhaustMap(() =>
this.defaultService.getCourierItems(
action.limit,
action.start,
action.end,
).pipe(
map(courierItems => CourierItemActions.loadCourierItemsSuccess({ courierItems })),
catchError(error =>
of(CourierItemActions.loadCourierItemsFailure({ error }))
)
)
)
))
)
)

另一个更新如果我使用这样的东西,我可以每秒获取一次,并且实体集合正在增长。但通过这种方法,我无法控制启动/停止。

let date = 1587513626000; // date is required because the backend only sends data with a start and end date
interval(1000).pipe(tap(_ => {
this.store.dispatch(loadStoreItems({ limit: 10, start: date, end: date + 1000 }))
date += 1000
}))
.subscribe()

还原器更新

export const reducer = createReducer(
initialState,
on(CourierItemActions.loadCourierItemsSuccess,
(state, action) => adapter.addMany(action.courierItems, state)
),
on(CourierItemActions.loadCourierItemsFailure,
(state, action) => {
return {
...state,
error: action.error
}
}
),

我尝试过addMany&addAll。。。两者都不起作用。只有来自第一个调用的项正在进入实体集合。但在后台,请求仍然每隔1秒继续一次。

UPDATE这是选择器。

export const selectCourierItemState = createFeatureSelector<CourierItemState>(
CourierItemsFeatureKey
);
export const selectCourierItems = createSelector(selectCourierItemState, selectAll);

如果您需要每秒发送一个请求的效果,则需要interval运算符。

//effects.ts
loadCourierItems$ = createEffect(() =>
this.actions$.pipe(
ofType(CourierItemActions.loadCourierItems),
exhaustMap(action => interval(1000).pipe(
startWith(0),
exhaustMap(step =>
this.defaultService.getCourierItems(
action.limit,
action.start + step * 1000,
action.end + step * 1000,
).pipe(
map(courierItems => CourierItemActions.loadCourierItemsSuccess({ courierItems })),
catchError(error =>
of(CourierItemActions.loadCourierItemsFailure({ error }))
)
)
),
),
takeUntil(this.actions$.pipe(ofType(CourierItemActions.pauseStreamingCourierItems))),
repeat(),
)
)
//app.component.ts
constructor(private store: Store<CourierItemsState>) {
}
ngOnInit() {
this.store.dispatch(loadCourierItems());
this.courierItems$ = this.store.pipe(select(selectCourierItems));
}
ngOnDestroy() {
this.store.dispatch(stopCourierItems());
}

您可能需要使用upsertMounty:添加或更新集合中的多个实体。支持部分更新。

on(CourierItemActions.loadCourierItemsSuccess,
(state, action) => adapter.upsertMany(action.courierItems, state)
),

最新更新