我在一个Angular应用程序中使用@ngrx,我想抽象一个我已经拥有的循环模式.
我的州通常由许多州组成,如下所示:
myState: { data: any isLoading: boolean isLoaded: boolean }
所以我最终在代码中做的是订阅它但我只想在状态已加载时收到通知.
this.store .select(state => state.myState) .filter(myState => myState.isLoaded) .map(myState => myState.data) .do(data => do_whatever_I_need_to_do) .subscribe();
这对我有用,但我想知道我是否可以简化前3个操作符,因为它们非常复发.
通过使用选择器,我可以创建这样的东西
const selectMyState = (state) => state.myState; export const getData = createSelector(selectMyState,state => state.data)
然后像这样使用它
this.store .select(getData) .do(data => do_whatever_I_need_to_do) .subscribe();
但后来我错过了过滤器部分,所以即使我的数据尚未加载,我也可能从中获取流事件.
有没有办法将这个丢失的过滤器包含在observable中?
我知道createSelector有一个函数作为param,所以我可以在那里做一些代码,但我不知道如何使用它来过滤不是数据,而是事件本身.
有任何想法吗?谢谢!
解决方法
对于那种我想重用流的一部分的场景,我创建了一个函数,它接受商店作为参数并对其进行一些操作.以下是一个例子:
const selectMyState = (state) => state.myState; export const getData = createSelector(selectMyState,state => state.data) export const getDataWhenLoaded = (store) => { return store.select(getData) .filter(myState => myState.isLoaded); }; ... getDataWhenLoaded(this.store).subscribe(...);
至于使用createSelector函数的最后一个参数,您可以根据需要进行操作.在documentation中,它提到传递给createSelector创建的memoized选择器的相同状态不会重新计算投影.它将在调用时返回相同的值.我找不到关于此的文档但是通过测试我注意到如果投影导致与前一个值相同的值,那么如果订阅已经收到先前的值,则不会发出它.与rxjs运算符distinctUntilChanged类似的行为.我没有时间挖掘他们的源代码来了解在哪里/如何/为什么.
因此,在某些情况下,您可以在createSelector的投影参数(最后一个)中放置一个过滤器.这是一个例子:
export const getActive = createSelector(selectMyData,state => state.data.filter(x => x.isActive));