10

store.select()发出先前的存储状态。

是否可以在不获取先前存储值的情况下从“这一点向前”订阅更改?

4

3 回答 3

12

如果您对第一个发出的值不感兴趣,您应该可以使用skip运算符:

store.select(...).skip(1)...
于 2016-08-15T12:04:18.963 回答
3

跳过操作员现在需要管道,您可以像这样使用跳过:

store.pipe(select(...), skip(1));

就“hacky”部分而言,ngrx 的标准做法是设置初始状态并将属性设置为 null。并且该值最初会发出。因此,在这些情况下,您获得的第一个值将为 null。

或者,您也可以考虑skipwhile(https://www.learnrxjs.io/learn-rxjs/operators/filtering/skipwhile)并像这样使用它:

store.pipe(select(...), skipWhile(val => val === undefined));

其中 undefined 是您感兴趣的属性的初始值。除了将属性的初始值设置为 undefined 之外,您也可以使用 null 作为初始值,并相应地更改上面的 skipwhile() 。

于 2020-06-21T02:32:20.283 回答
0

在阅读@Niz 的回答后分享我的想法(和解决方案)。

null这是一个完美、实用的例子,说明了如何利用和之间的差异undefined。当你用 null 初始化你的状态时,你基本上是在说:

我不在乎将可空的未来状态与初始状态区分开来。我不在乎用户是 null 是因为他已经退出还是因为他没有登录

然而,在某些情况下,这可能是不够的。考虑一下您需要异步调用(在 中实现effects)以了解您是否有活动的用户会话的情况。根据selection 结果,您应该确定是显示登录模式还是重定向到内容页面。将初始用户状态设置为 null,您将弹出该模式,然后在该异步调用返回会话值时立即隐藏它。

将初始状态设置为undefined您可以进行区分,说:

最初,我对自己的状态一无所知,然后是undefined. 当我知道它应该为空时,我会将其设置为null.

因此,作为一个实用的解决方案,我将应用程序上的所有内容设置initialStateundefined. 在上面的示例中,我需要知道在异步调用解决后是否应该显示登录模式。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...
    });
}
于 2021-03-09T09:18:12.763 回答