Ngrx 存储 take(1),但在注销/登录后重置
Posted
技术标签:
【中文标题】Ngrx 存储 take(1),但在注销/登录后重置【英文标题】:Ngrx store take(1), but reset after logout/login 【发布时间】:2021-11-02 08:15:45 【问题描述】:所以,假设您有一个带有书籍列表的 ngrx 商店。
当您登录到您的个人资料页面时,您可以使用以下方式获取您的图书:
this.store.dispatch(getBooks());
哪个会触发效果:
getBooks$ = createEffect(() =>
this.actions.pipe(
ofType(A.getBooks),
switchMap(() =>
this.bookService.getBooks().pipe(
map((books) => A.getBooksOk( books )),
catchError(() => EMPTY),
),
),
),
);
但是,您不希望每次导航到个人资料页面时都触发此效果,因为您只需要获取图书一次。
所以你添加take(1)
:
getBooks$ = createEffect(() =>
this.actions.pipe(
ofType(A.getBooks),
take(1),
switchMap(() =>
...
现在的问题是,如果您注销然后登录到另一个配置文件,则商店将不会获取您的图书,因为该效果已由先前的配置文件触发。
对此的明显解决方案是不使用take(1)
,而是在商店中设置另一个变量booksLoaded
,您可以使用它来检查您是否应该得到这些书。
但是,这非常乏味,因为您需要为存储中的每个变量使用这些“加载”变量之一,并添加一堆额外的代码来管理这些变量。
所以,问题是:有没有办法让效果只触发一次(如take(1)
),但是当您注销并重新登录时,您允许效果再次触发(只触发一次)?
编辑: 您也可以只检查效果中是否未定义书籍。 但是,在您从服务器获得响应之前,仍然可能会多次触发该效果,因此它并不总是有效。
【问题讨论】:
IMO 标记数据是否已加载的策略是一个非常好的策略,因为它可以让您更好地控制注销/登录问题。在注销操作+reducer 中,您将清除该标志,并且将为新登录的用户重新加载数据。这比拥有take(n)
的效果要好得多,否则应该保持活力。该标志也可以是一个日期戳,以便您可以确定它是否过时并需要刷新。不要担心 - 我认为这是一个不错的选择 :)
【参考方案1】:
我不知道您为什么认为仅检查您是否已有数据很麻烦。您不一定需要新变量,只需检查您的结果是否已设置。
getBooks$ = createEffect(() =>
this.actions.pipe(
ofType(A.getBooks),
withLatestFrom(this.store.select(S.selectBooks)),
exhaustMap(([, books]) =>
iif(
() => books,
of(A.getBooksOk( books )),
this.bookService.getBooks().pipe(
map((books) => A.getBooksOk( books )),
catchError(() => EMPTY),
),
),
),
),
);
只要确保在有意义的地方(例如注销时)清除减速器中的书籍即可。
【讨论】:
如果在从服务器接收到数据之前多次调用“this.store.dispatch(getBooks())”,这将不起作用。不是说这应该经常发生,只是这不是万无一失的。 当然该操作可能会启动多次,但它只会调用this.bookService.getBooks()
iff您商店中的书籍未设置。如果书籍已经被检索,它会立即返回。
我们实际上是在做:if I already have the books, then return the books, otherwise, get the books from the service
当然,这是假设操作 A.getBooksOk
实际上存储了结果,并且将来可以使用选择器 S.selectBooks
访问。
我刚刚重读了您的评论,在这种情况下,您可能希望使用exhaustMap
而不是switchMap
。因为exhaustMap
将忽略未来的更新,直到第一次解决。继续类比,if I already have the books, then return the books, otherwise, get the books from the service, but don't bug me until I know for sure
以上是关于Ngrx 存储 take(1),但在注销/登录后重置的主要内容,如果未能解决你的问题,请参考以下文章
从 ASP.NET MVC 客户端应用程序和 .NET 5 openiddict 服务器注销。注销后重定向 URL 无效