ngrx 4 选择器返回整个状态而不是子状态
Posted
技术标签:
【中文标题】ngrx 4 选择器返回整个状态而不是子状态【英文标题】:ngrx 4 selectors returning entire state instead of sub states 【发布时间】:2018-07-06 10:21:15 【问题描述】:出于某种原因,我的所有选择器都返回了整个状态对象,而不是我认为应该返回的子状态。例如,我试图从 reducers/customer.ts 返回客户状态,但我从 index.ts 中获取了一个包含整个状态的对象。
在检查了 github 上的 ngrx 示例应用程序后,我选择了下面的特定结构,显然我做错了什么。
文件结构:
这是actions/customer.ts:
import Action from '@ngrx/store';
import State from '../reducers/customer';
export enum CustomerActionTypes
Add = '[Customer] Add Selected Customer to Store'
export class Add implements Action
readonly type = CustomerActionTypes.Add;
constructor(public payload: State)
console.log("from action: " + JSON.stringify(payload,null,2));
export type CustomerActions = Add
还有reducers/customer.ts:
import ActionReducer, Action from '@ngrx/store';
import CustomerActionTypes, CustomerActions from '../actions/customer';
export interface State
name: string;
status: string;
phone: string;
stage: string;
type: string;
id: string;
street: string;
city: string;
postalCode: string;
email: string;
state: string;
export function reducer(
state: State,
action: CustomerActions
): State
switch (action.type)
case CustomerActionTypes.Add:
return action.payload
default:
return state;
export const getCustomerState = (state: State) => state;
还有reducers/index.ts:
//For reducers map
import * as fromMainNav from './main-nav-ui';
import * as fromTradeUI from './trade-ui';
import * as fromAppts from './appointments';
import * as fromCustomer from './customer';
//Whole application state
export interface State
mainNavUI: fromMainNav.State;
tradeUI: fromTradeUI.State;
appointments: fromAppts.State;
selectedCustomer: fromCustomer.State;
//Reducer map
export const reducers =
mainNavUI: fromMainNav.reducer,
tradeUI: fromTradeUI.reducer,
appointments: fromAppts.reducer,
selectedCustomer: fromCustomer.reducer
;
并在 app.module.ts 中导入:
imports: [
...
StoreModule.forRoot(reducers)
],
最后我是如何将它连接到一个组件中并使用选择器的:
...
import * as fromCustomer from '../../../shared/state/reducers/customer';
...
public cust$: Observable<fromCustomer.State>;
constructor(
...
public ngrxStore: Store<fromCustomer.State>
)
this.cust$ = ngrxStore.select(fromCustomer.getCustomerState);
任何帮助将不胜感激,谢谢!
【问题讨论】:
【参考方案1】:尝试在reducers/index.ts
中使用createFeatureSelector 以从***功能状态开始:
export const getAppState = createFeatureSelector<State>('wholeApp');
然后在不同的选择器中使用它来访问您的客户减速器:
export const getCustomer = createSelector(
getAppState,
(state: State) => state.selectedCustomer
);
从那里你可以通过链接选择器继续深入你的状态,例如,如果你的组件只需要知道客户的电子邮件地址,它可以订阅这个:
export const getEmail = createSelector(
getCustomer,
(state: fromCustomer.State) => state.email
);
有关更多详细信息(和示例),我建议查看 Todd Motto 的这篇精彩文章:
https://ultimatecourses.com/blog/ngrx-store-understanding-state-selectors
【讨论】:
非常感谢,这很有意义。作为一种解决方法,我刚刚将它们全部移入索引,但我更喜欢这种方法。 你能解释一下,'wholeApp'-string 是从哪里来的吗?谢谢。 @EternalBeginner 这是你给你的状态起的名字,它可以是一个像products
或pizza
或只是app
这样的模块。我刚刚添加了一篇可以更好地解释它的精彩文章的链接。【参考方案2】:
Salem 为您提供了一个很好的解决方案,但您的问题的根本原因是应用程序组件中的这一行。
this.cust$ = ngrxStore.select(fromCustomer.getCustomerState);
您的 fromCustomer.getCustomerState 定义如下:
export const getCustomerState = (state: State) => state;
由于 ngrxStore.select 将始终返回根状态,当然您仍将根据您定义此 getCustomerState 函数的方式获取根状态。您的 getCustomerState 函数不进行任何转换,它只返回传递的任何内容通过。
【讨论】:
以上是关于ngrx 4 选择器返回整个状态而不是子状态的主要内容,如果未能解决你的问题,请参考以下文章
在单元测试中:如何覆盖由 entityAdapter.getSelectors() 创建的 NGRX 选择器