我有一个简单的简单ngrx结构,该结构从REST端点加载JSON数组并将其置于状态。它不会一次加载整个数组,而是一次加载30个元素的页面,并将结果附加到先前加载的内容上。所以这是典型的分页。重复执行负责整个操作的操作,并使用一个参数指定要加载的页码。它调用一个效果,然后又调用一种服务的方法。
问题是,在第一次调用后,该操作根本无法执行。在第一次通话时,它运行完美。在第二次,第三次等尝试时,它似乎在act()
运算符之前停止了,但它不会引发任何错误或完全不执行任何操作。
这是动作:
export const LoadSiteList = createAction(
ActionTypes.LoadSiteList,
props<{ page: number }>()
);
效果:
loadSiteList = createEffect(() => this.actions.pipe(
ofType(LoadSiteList),
act({
project: payload => {
return this.sitesService.loadSiteList(payload['page']).pipe(
map((siteList: Site[]) => UpdateSiteList({ siteList })),
)
},
error: () => { alert('Unable to load site list!'); return DoNothing() }
})
));
sitesService
中的服务方法:
loadSiteList(page: number = 1): Observable<any> {
return Observable.create(observer => {
const temp = this.httpClient.get(`${environment.rootUrl}sites?_page=${page}`)
.subscribe(
data => observer.next(data),
error => observer.error(error),
() => temp.unsubscribe()
);
});
}
这就是我从组件中调用的方式:
this.store.dispatch(LoadSiteList({ page: this.page }));
我很确定这不是丢失的导入,因为那时它根本不起作用。服务方法中的unsubscribe()
也没有问题。我试图在效果中将tap()
运算符放在ofType()和map()
之间,并且它会触发,所以动作确实到达了。 act()
运算符的回调分支中的任何控制台输出都不会出现,因此不会触发该运算符。但是为什么呢?
以防万一,这也是reducer方法。它永远不会被调用。
on(
SitesActions.UpdateSiteList,
(state, siteList) => ({
...state,
sites: [...state.sites, ...siteList.siteList]
})
),
没有什么比回答我自己的问题更感到傻了。因此,似乎错误在于效果的管道结构。这是工作版本:
loadSiteList$ = createEffect(() => this.actions$.pipe(
ofType(LoadSiteList),
map(payload => payload['page']),
mergeMap(page => this.sitesService.loadSiteList(page)
.pipe(
map((siteList: Site[]) => UpdateSiteList({ siteList })),
catchError(error => { alert(`Error ${error.status} loading data.`); return EMPTY; })
))
));
[另一个经验教训:当您不想从效果中分派另一个动作时,ngrx的值为EMPTY
。了解的越多。