@ngrx/store 忽略第一个发出的值
@ngrx/store Ignore first emitted value
store.select()
发出先前的存储状态。
是否可以订阅来自 "this point forward" 的更改而不获取以前的存储值?
如果您对第一个发出的值不感兴趣,您应该可以使用 skip
运算符:
store.select(...).skip(1)...
skip 运算符现在需要管道,您可以像这样使用 skip:
store.pipe(select(...), skip(1));
就 'hacky' 部分而言,ngrx 中的标准做法是将属性设置为 null 来设置初始状态。并且该值最初被发出。所以在这些情况下你得到的第一个值将为空。
或者你也可以考虑 skipwhile(https://www.learnrxjs.io/learn-rxjs/operators/filtering/skipwhile) 并像这样使用它:
store.pipe(select(...), skipWhile(val => val === undefined));
其中 undefined 是您感兴趣的 属性 的初始值。除了将 属性 的初始值设置为 undefined 之外,您还可以使用 null 作为初始值,并相应地更改上面的 skipwhile()。
阅读@Niz 的回答后分享我的想法(和解决方案)。
这是一个完美的实用示例,说明如何利用 null
和 undefined
之间的差异。当你用 null 初始化你的状态时,你基本上是在说:
I don't care about differentiating the nullable future state from the
initial one. I don't care if the user is null because he has signed
out or because he just didn't sign in
但是,在某些情况下,这可能还不够。想一想您需要异步调用(在 effects
中实现)以了解您是否有活动用户会话的情况。根据 select
ion 结果,您应该确定是显示登录模式还是重定向到内容页面。将初始用户状态设置为 null,您将弹出该模式,然后在异步调用 returns 会话值时立即将其隐藏。
将初始状态设置为 undefined
您可以进行区分,说:
Initially, I know nothing about my state, then it's undefined
. When I know it should be empty, then I'll set it to null
.
因此,作为一个实用的解决方案,我将应用程序 initialState
上的所有内容都设置为 undefined
。在上面的示例中,我需要知道在异步调用解决后是否应显示登录模式。 skipWhile(val => val === undefined)
肯定能完成这项工作,但一遍又一遍地重复感觉有点乏味。另外,它并没有真正描述我们的用例。我创建了一个 rxjs-custom-operators.ts
并缩短了实现:
import { Observable } from "rxjs";
import { skipWhile } from "rxjs/operators";
export const skipInitial = () => {
return <T>(source: Observable <T>): Observable<T> => {
return source.pipe(skipWhile(value => value === undefined));
};
};
用法:
navigateOnLoad(): void {
this.store.pipe(select(selectAuthUser), skipInitial()).subscribe((authUser: CognitoUser) => {
// Navigate to login if !authUser, else navigate to content...
});
}
store.select()
发出先前的存储状态。
是否可以订阅来自 "this point forward" 的更改而不获取以前的存储值?
如果您对第一个发出的值不感兴趣,您应该可以使用 skip
运算符:
store.select(...).skip(1)...
skip 运算符现在需要管道,您可以像这样使用 skip:
store.pipe(select(...), skip(1));
就 'hacky' 部分而言,ngrx 中的标准做法是将属性设置为 null 来设置初始状态。并且该值最初被发出。所以在这些情况下你得到的第一个值将为空。
或者你也可以考虑 skipwhile(https://www.learnrxjs.io/learn-rxjs/operators/filtering/skipwhile) 并像这样使用它:
store.pipe(select(...), skipWhile(val => val === undefined));
其中 undefined 是您感兴趣的 属性 的初始值。除了将 属性 的初始值设置为 undefined 之外,您还可以使用 null 作为初始值,并相应地更改上面的 skipwhile()。
阅读@Niz 的回答后分享我的想法(和解决方案)。
这是一个完美的实用示例,说明如何利用 null
和 undefined
之间的差异。当你用 null 初始化你的状态时,你基本上是在说:
I don't care about differentiating the nullable future state from the initial one. I don't care if the user is null because he has signed out or because he just didn't sign in
但是,在某些情况下,这可能还不够。想一想您需要异步调用(在 effects
中实现)以了解您是否有活动用户会话的情况。根据 select
ion 结果,您应该确定是显示登录模式还是重定向到内容页面。将初始用户状态设置为 null,您将弹出该模式,然后在异步调用 returns 会话值时立即将其隐藏。
将初始状态设置为 undefined
您可以进行区分,说:
Initially, I know nothing about my state, then it's
undefined
. When I know it should be empty, then I'll set it tonull
.
因此,作为一个实用的解决方案,我将应用程序 initialState
上的所有内容都设置为 undefined
。在上面的示例中,我需要知道在异步调用解决后是否应显示登录模式。 skipWhile(val => val === undefined)
肯定能完成这项工作,但一遍又一遍地重复感觉有点乏味。另外,它并没有真正描述我们的用例。我创建了一个 rxjs-custom-operators.ts
并缩短了实现:
import { Observable } from "rxjs";
import { skipWhile } from "rxjs/operators";
export const skipInitial = () => {
return <T>(source: Observable <T>): Observable<T> => {
return source.pipe(skipWhile(value => value === undefined));
};
};
用法:
navigateOnLoad(): void {
this.store.pipe(select(selectAuthUser), skipInitial()).subscribe((authUser: CognitoUser) => {
// Navigate to login if !authUser, else navigate to content...
});
}