在使用observables使用NGRX调用API之前,检查Angular Store中的数据

时间:2018-06-05 17:25:58

标签: angular observable ngrx-store ngrx-effects

我正在使用Angular和NGRX效果,我是可观察世界的新手。我想检查一下,如果我的商店中存在数据,那么就不应该调用API,并且应该从商店中提取数据。我设法发现我可以使用withLatestFrom()来检查商店中的最新值。下一部分让我感到困惑,我无法让它发挥作用。我目前的代码如下:

 @Effect() getSomeContent$ = this.actions$
    .ofType(GET_SOME_CONTENT)
    .withLatestFrom(this.store$.select('store-section'))
    .map(([action, store]) => {
        const content = {};
        if (store.someContent.length > 0) {
           return new GetCategoryContentSuccessAction({ categoryContent: categories });
        }
        return Observable.from(action.payload);
    })
    .switchMap(payload => this.APIcall(payload)
        .then(data => {
            const content = {};
            data.items.map((item) => {
                const slug = data.slug;
                content[slug] = {
                    info: datasomeData
                };
            });
            return new GetSomeContentSuccessAction({ categoryContent: categories });
        })
        .catch((err) => {
            return new GetFailureAction({ error: {} });
        })
    );

我想使用某种if或else语句来检查商店。如果数据存在,我想为我必须处理的reducer发送一个空对象。如果不是,我想调用API并将数据发回。我不知道观察结果是否可以分支,所以可以这样做?

有没有更好的方法可以实现这一目标?可能通过创建另一个动作来单独处理API。我想了解最佳实践是什么。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

我只是在解决这个确切的问题,所以我想把2美分放在这里,以防其他人发现它有用。

有一篇很棒的文章Sto Using NGRX Effects For That。上面讨论了在ngrx效果链中塞满这个代码有多复杂。

相反,他们建议使用我一直在使用并喜欢的服务。一个简单的版本可能看起来像这样。

Service: 

public posts$ = this.store.select(postSelectors.selectAll)
    .pipe(
        tap(posts => {
            if (!posts.length) {
                this.store.dispatch(new postActions.LoadMany());
            }
        }),
        filter(posts => posts !== null)
    );

在这里,我们基本上只是尝试选择所需的状态,如果状态不存在,则调度一个动作,该动作将触发一个效果,将其从api中获取并将其推入商店。

Component: 

this.posts$ = this.postService.posts$;

然后,您可以在组件中订阅服务中的可观察对象,而不必关心它是否在商店中。然后,您可以在组件中订阅该值以获取值,也可以使用异步管道将其推送到模板。

这对于简单的东西确实非常有效,但是当您必须先获取依赖于其他数据的数据时,我仍在研究更复杂的RXJS链。但是,那只是我编写RXJS函数的能力的限制。