无法从Ngrx实体Selector获取的prsnl数据中访问firstname字段
解决Ngrx实体中获取firstname属性的问题
1. 修正你的Selector
你的selectAllPrsnls写法存在问题:prsnlsState是Ngrx实体状态(包含ids和entities字段),直接Object.values(prsnlsState)会把ids数组和entities对象都混入结果,这不是你需要的实体列表。正确写法应该直接从entities中提取实体:
export const selectAllPrsnls = createSelector( selectPrsnlState, prsnlsState => Object.values(prsnlsState.entities) // 提取entities中的所有实体对象 );
如果需要保持ids定义的顺序(Ngrx实体默认按ids顺序返回数据),可以结合ids映射:
export const selectAllPrsnls = createSelector( selectPrsnlState, prsnlsState => prsnlsState.ids.map(id => prsnlsState.entities[id]) );
2. 修正数据获取逻辑
你的getAllPersnlValues有两个核心问题:
subscribe是异步操作,外部的console.log会在赋值前执行,导致打印结果为undefined- 直接赋值
value.entities得到的是键为id、值为实体的对象,需要进一步提取属性
修改后的代码可以直接用修正后的selectAllPrsnls获取实体列表,再提取firstname:
getAllPersnlValues() { this.store .pipe(select(selectAllPrsnls)) // 使用修正后的Selector .subscribe(prsnlList => { // 提取所有firstname,得到纯字符串数组 this.allprsnl = prsnlList.map(prsnl => prsnl.firstname); console.log("All prsnl firstnames", this.allprsnl); }); }
如果不想提前定义Selector,也可以在pipe中直接处理:
getAllPersnlValues() { this.store .pipe( select(selectPrsnlState), map(state => Object.values(state.entities)), // 转换为实体数组 map(prsnlList => prsnlList.map(prsnl => prsnl.firstname)) // 提取firstname ) .subscribe(firstnames => { this.allprsnl = firstnames; console.log("All prsnl firstnames", this.allprsnl); }); }
额外提示
- 如果你是用
createEntityAdapter创建的Ngrx实体,可以直接使用适配器自带的selectAllSelector,无需手动编写:// 假设已定义实体适配器 const prsnlAdapter = createEntityAdapter<Prsnl>(); const { selectAll } = prsnlAdapter.getSelectors(); export const selectAllPrsnls = createSelector( selectPrsnlState, selectAll ); - 异步操作中推荐用
async管道在模板中订阅,避免直接在subscribe里赋值:
模板代码:
组件代码:<ul> <li *ngFor="let firstname of allprsnl$ | async">{{ firstname }}</li> </ul>allprsnl$: Observable<string[]>; ngOnInit() { this.allprsnl$ = this.store.pipe( select(selectAllPrsnls), map(prsnlList => prsnlList.map(p => p.firstname)) ); }
内容的提问来源于stack exchange,提问作者Prenam
相关产品推荐
相关产品推荐

