- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我刚遇到 custom selectors @ngrx
的作者,我根本不会对这个功能感到惊讶。
根据他们对 selectedUser
的 books
使用案例,我无法给出使用自定义选择器的真正充分理由,例如:
export const selectVisibleBooks = createSelector(selectUser, selectAllBooks, (selectedUser: User, allBooks: Books[]) => {
return allBooks.filter((book: Book) => book.userId === selectedUser.id);
});
而不是类似的东西:
export const selectVisibleBooks = Observable.combineLatest(selectUser, selectAllBooks, (selectedUser: User, allBooks: Books[]) => {
return allBooks.filter((book: Book) => book.userId === selectedUser.id);
});
我试图说服自己 memoization createSelector
是关键部分,但据我所知,它无法对非原始值执行这些性能提升,因此它不会真正节省非原始切片的任何计算,通过使用 Rx
的 distinctUntilChanged
用combineLatest
运算符可以解决。
那么我错过了什么,为什么要使用@ngrx/selector
?
提前感谢您的任何见解。
最佳答案
也许它不仅仅是内存,但我没有看到任何在 source code 中脱颖而出的东西. docs 中宣传的所有内容是记忆化和一种重置它的方法,您基本上也可以使用不同的运算符来完成。我会说使用它的原因是它很方便。至少在简单的情况下,它比将不同的运算符绑定(bind)到 combineLatest
的每个输入上更方便。
另一个好处是它允许您集中与状态的内部结构相关的逻辑。您可以为其创建一个选择器并执行 store.select(selectBaz)
,而不是到处都执行 store.select(x => foo.bar.baz)
。您可以将选择器组合到。通过这种方式,您只需要在一个地方设置遍历状态树的逻辑。如果您必须更改状态的结构,这是有益的,因为您只需在一个地方进行更改,而不用查找每个选择器。不过,每个人都可能不喜欢添加更多样板文件。但作为一个必须对状态进行重大重构的人,我只使用选择器。
createSelector
非常基础,因此您只能将其用于基本类型的操作。在您检索只需要过滤子集的对象列表的情况下,它就不够用了。这是一个例子:
const selectParentVmById = (id: string) => createSelector<RootState, Parent, Child[], ParentVm>(
selectParentById(id),
selectChildren(),
(parent: Parent, children: Child[]) => (<ParentVm>{
...parent,
children: children.filter(child => parent.children.includes(child.id))
})
);
在这种情况下,选择器 selectParentVmById
将在 selectChildren()
发出一个不同的数组时发出,如果其中的任何元素发生变化,就会发生这种情况。如果改变的元素是 parent 的 child 之一,这很好。如果不是,那么你会得到不必要的流失,因为内存是在整个列表而不是过滤列表(或者更确切地说是其中的元素)上完成的。我有很多这样的场景,并且已经开始只对简单的选择器使用 createSelector
并将它们与 combineLatest
结合起来并滚动我自己的内存。
这不是一般不使用它的理由,您只需要了解它的局限性即可。
你的问题不是关于这个的,但自从我提出这个问题后,我想我会给出完整的解决方案。我开始使用名为 distinctElements()
的自定义运算符,它的作用类似于 distinctUntilChanged()
但应用于列表中的元素而不是列表本身。
这是运算符:
import { Observable } from 'rxjs/Observable';
import { startWith, pairwise, filter, map } from 'rxjs/operators';
export const distinctElements = () => <T extends Array<V>, V>(source: Observable<T>) => {
return source.pipe(
startWith(<T>null),
pairwise(),
filter(([a, b]) => a == null || a.length !== b.length || a.some(x => !b.includes(x))),
map(([a, b]) => b)
)
};
这里将重构上面的代码以使用它:
const selectParentVmById = (store: Store<RootState>, id: string): ParentVm => {
return store.select(selectParentById(id)).pipe(
distinctUntilChanged(),
switchMap((parent) => store.select(selectChildren()).pipe(
map((children) => children.filter(child => parent.children.includes(child.id))),
distinctElements(),
map((children) => <ParentVm> { ...parent, children })
))
);
}
需要更多的代码,但它减少了浪费的工作。您可以根据您的情况添加 shareReplay(1)
。
关于angular - ngrx - createSelector 与 Observable.combineLatest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48187479/
我已经建立了这个IStore: export interface IStore { user: IUser; sources: ISourceRedux; } 其中IUser是: export
store.select()发出先前的存储状态。 是否可以订阅从“此刻开始”的更改,而无需获取先前的商店值(value)? 最佳答案 如果您对第一个发出的值不感兴趣,则应该可以使用 skip 运算符:
我已将我的 ngrx 代码更新到版本 8(使用 Action Creator 等),但我现在不知道如何在 NgRx Store DevTools 中使用 Dispatcher。 在我能够发送这样的操作
我正在开发一个新的 angular 4 plus @ngrx 4 项目。 我希望对加载的数据具有搜索功能。 例如,所有联系人信息都已加载到组件中。 联系人列表将过滤与搜索文本匹配的联系人姓名。 Ple
我正在使用 Ngrx 和 Angular2 构建一个移动应用程序。当用户从我的应用程序中注销时,我想清除商店?谁能知道该怎么做? 最佳答案 您应该在每个 reducer 中有一个明确的操作,这将清理商
我看到很多代码示例,其中 store.dispatch() 调用直接发生在 Angular 组件中。让一个愚蠢的 Angular 组件访问整个 Store 不是很糟糕吗?为什么不将所有的 Action
ngrx 的支持者声称 (here for example),您可以并且应该将所有应用程序状态保存在单个 Store 中。这表明 @ngrx/Store 可以用于缓存,因为缓存的内容是一种应用程序状态
我的应用程序在调度某个 Action 时没有调度某些 Action 或某些效果没有被调用,这有问题(请参阅 ngrx effect not being called when action is di
下面的代码片段有什么作用?取自此 file . export const getCollectionLoading = createSelector(getCollectionState, fromC
如果在同一个商店上分派(dispatch)多个操作: store.dispatch(new SomeAction()); store.dispatch(new SomeOtherAction());
我试图了解 typeof 效果在 ngrx 中是如何工作的,如果我在我的应用程序模块中声明: .... @NgModule({ imports: [ EffectsModule
任何人都可以建议在角度应用程序中使用 ngrx 进行状态管理时如何控制台记录状态。我已经浏览了 ngrx-store-logger,但是文档并不清楚如何创建元 reducer 和使用这个库。 最佳答案
我一直在阅读ngrx示例应用程序的代码并找到两个函数调用 createFeatureSelector('auth'); 和 createSelector(selectAuthState,(state:
我正在使用 Angular 8 和 NGRX 8。我有一个操作: export const loadEnvironment = createAction( LicencingActionTypes
我正在使用 Angular 8 和 NGRX 8。我有一个操作: export const loadEnvironment = createAction( LicencingActionTypes
以下示例取自 @ngrx example . 我以这种方式理解这个 observable。第一map函数获取 payload这是要添加的书,再次由mergeMap处理它保存到数据库的位置。 原码:
我目前正在使用 NgRx Data 对我项目中的几个实体执行 CRUD 操作。现在,我必须开发分页。因此,REST API 响应将如下所示: { "page": 1, "per_pag
如何在 NGRX 中访问(读取)另一个 reducer 中的 reducer 状态?这是一个与 this 非常相似的问题.NGRX 是否为此提供任何其他解决方案? 最佳答案 我在考虑做类似的事情时偶然
我正在尝试按属性过滤掉有效负载数据。 //reducer.ts case MessagesActionTypes.LOAD_Message_SUCCESS: { console.lo
我有效果类,我想根据路由器参数 ID 加载详细信息 @Effect() getDetails$ = this.actions$.ofType(DetailActions.GET_DETAILS).
我是一名优秀的程序员,十分优秀!