使用 ngrx/store 时多次分派
Multiple dispatches while using ngrx/store
我正在开发示例 Angular 2 应用程序,并使用 ngrx/store 和 ngrx/effects 进行状态管理。
下图描述了我的应用程序的屏幕之一。
为了显示来自服务器的图书列表、类别和作者,对商店进行了以下调度调用。
this.store.dispatch(loadCatgories());
this.store.dispatch(loadAuthors());
this.store.dispatch(loadBooks());
下面是相关的效果
@Effect() authors$ = this.actions$
.ofType(AuthorActionTypes.LOAD_AUTHORS)
.switchMap(() => this.authorService.loadAuthors())
.map(authors => loadAuthorsSuccess(authors));
@Effect() categories$ = this.actions$
.ofType(CategoryActionTypes.LOAD_CATEGORIES)
.switchMap(() => this.service.loadCategories())
.map(categories => loadCategoriesSuccess(categories));
@Effect() books$ = this.actions$
.ofType(BookActionTypes.LOAD_BOOKS)
.switchMap(() => this.bookService.loadBooks())
.map(books => loadBooksSuccess(books));
我的问题是
上面的方法是否正确,或者有什么更好的方法吗,由于某些原因,有时书籍列表显示一秒钟,然后它们就消失了。
如果我的理解是正确的,以上三个调度是并行发生的,如果我需要它们一个接一个发生怎么办。
为什么单独加载这些项目不是一个好主意?
多个 HTTP 请求会降低您的应用速度
- 在网络不佳的情况下,这可能需要很长时间
- 每次收到响应时触发更改检测(至少 3 次而不是 1 次)
如果您想组合数据,例如使用选择器,您可能会以存储不一致而告终,而您不希望这种情况发生
你应该怎么做?
只做一个请求(我想你也是设计后端的那个)。
你可能只是 return 类似的东西:
{
authors: ...,
categories: ...,
books: ...
}
然后你有两个选择:分派一个成功的动作,你将在你的 3 个减速器中分别处理,或者使用像 redux-batched-actions 这样的库并执行以下操作:
批量操作([
加载作者成功(res.authors),
加载类别成功(res.categories),
加载图书成功(res.books)
])
这样,您的商店将保持一致,因为只会发生一次发货。
如果没有修改后台的可能,使用forkJoin
同时发起请求,等待3个请求结束后再发送(一次)。
编辑:
有用的链接 :
- https://www.youtube.com/watch?v=mhA7zZ23Odw
- http://onehungrymind.com/handle-multiple-angular-2-models-ngrx-computed-observables/
- https://github.com/btroncone/ngrx-examples
- http://onehungrymind.com/build-better-angular-2-application-redux-ngrx/
我很喜欢这个http://bodiddlie.github.io/ng-2-toh-with-ngrx-suite/
一旦你对 ngrx/store 和 ngrx/effects 有了更好的理解,你也可以看看这个 repo:https://github.com/teropa/harmonics-explorer
同时还有 ngrx-batch-action-reducer。您可以像 "LoadBookList" 一样定义 "batch action" 并可以用它定义多个操作。
我正在开发示例 Angular 2 应用程序,并使用 ngrx/store 和 ngrx/effects 进行状态管理。
下图描述了我的应用程序的屏幕之一。
为了显示来自服务器的图书列表、类别和作者,对商店进行了以下调度调用。
this.store.dispatch(loadCatgories());
this.store.dispatch(loadAuthors());
this.store.dispatch(loadBooks());
下面是相关的效果
@Effect() authors$ = this.actions$
.ofType(AuthorActionTypes.LOAD_AUTHORS)
.switchMap(() => this.authorService.loadAuthors())
.map(authors => loadAuthorsSuccess(authors));
@Effect() categories$ = this.actions$
.ofType(CategoryActionTypes.LOAD_CATEGORIES)
.switchMap(() => this.service.loadCategories())
.map(categories => loadCategoriesSuccess(categories));
@Effect() books$ = this.actions$
.ofType(BookActionTypes.LOAD_BOOKS)
.switchMap(() => this.bookService.loadBooks())
.map(books => loadBooksSuccess(books));
我的问题是
上面的方法是否正确,或者有什么更好的方法吗,由于某些原因,有时书籍列表显示一秒钟,然后它们就消失了。
如果我的理解是正确的,以上三个调度是并行发生的,如果我需要它们一个接一个发生怎么办。
为什么单独加载这些项目不是一个好主意?
多个 HTTP 请求会降低您的应用速度
- 在网络不佳的情况下,这可能需要很长时间
- 每次收到响应时触发更改检测(至少 3 次而不是 1 次)
如果您想组合数据,例如使用选择器,您可能会以存储不一致而告终,而您不希望这种情况发生
你应该怎么做?
只做一个请求(我想你也是设计后端的那个)。 你可能只是 return 类似的东西:
{
authors: ...,
categories: ...,
books: ...
}
然后你有两个选择:分派一个成功的动作,你将在你的 3 个减速器中分别处理,或者使用像 redux-batched-actions 这样的库并执行以下操作: 批量操作([ 加载作者成功(res.authors), 加载类别成功(res.categories), 加载图书成功(res.books) ])
这样,您的商店将保持一致,因为只会发生一次发货。
如果没有修改后台的可能,使用forkJoin
同时发起请求,等待3个请求结束后再发送(一次)。
编辑:
有用的链接 :
- https://www.youtube.com/watch?v=mhA7zZ23Odw
- http://onehungrymind.com/handle-multiple-angular-2-models-ngrx-computed-observables/
- https://github.com/btroncone/ngrx-examples
- http://onehungrymind.com/build-better-angular-2-application-redux-ngrx/
我很喜欢这个http://bodiddlie.github.io/ng-2-toh-with-ngrx-suite/
一旦你对 ngrx/store 和 ngrx/effects 有了更好的理解,你也可以看看这个 repo:https://github.com/teropa/harmonics-explorer
同时还有 ngrx-batch-action-reducer。您可以像 "LoadBookList" 一样定义 "batch action" 并可以用它定义多个操作。