NgRx 无法从商店中选择
Posted
技术标签:
【中文标题】NgRx 无法从商店中选择【英文标题】:NgRx can't select from store 【发布时间】:2018-03-25 20:45:05 【问题描述】:我正在做一个非常简单的 NgRx 实现,现在只是为一个组件做 get。根据 Redux Devtool,数据来自有效负载,但我似乎无法通过异步管道访问它。
开发工具:
---更新----
问题是当我访问我的 ts 文件中的切片时,我得到了错误
“网络”类型的参数不能分配给类型参数 '“开始”'。
ts 文件
constructor(private store: Store<fromApp.AppState>)
getDns()
// reach out to ngrx store
this.dnsServers$ = this.store.select('network').map(network => network.dns)
console.log(this.dnsServers$)
// get current dns IPs'
this.networkService.getDns()
.subscribe(
(dnsList: Dns) =>
console.log(dnsList.dns);
this.store.dispatch(
new LoadIpSuccessAction(dnsList.dns)
)
)
我的功能模块
StoreModule.forFeature('network', dns: dnsReducer )
我的根减速器(我没有任何模块没有延迟加载,所以我的根减速器是空的......不知道如何让它工作)
import Action from '@ngrx/store';
export interface State
start: string;
const initialState: State =
start: ''
export function startReducer(state = initialState, action: Action)
return state;
和我更新的功能缩减器来访问 dns 数组
import * as NetworkActions from './network.actions';
import * as fromApp from '../../store/app.reducers';
export interface NetworkState extends fromApp.AppState
dns: DnsState;
export interface DnsState
dns: string[];
const initialState: DnsState =
dns: []
export function dnsReducer(state = initialState, action: NetworkActions.DnsActions)
switch (action.type)
case NetworkActions.LOAD_IP_SUCCESS:
return
...state,
dns: [...action.payload]
default:
return state;
【问题讨论】:
尝试在 getDns() 之外设置 dnsServer = this.store.select('dns') 的定义。如果您使用类型,还要将 dnsServer 的类型设置为 Obseravble。 getDns() 在 ngOninit() 中被调用,所以它是否在外面无关紧要。我最终会输入可观察的,但这并不能解决问题 我想我知道。返回的有效负载对象可能与订阅获取的值不同,然后立即设置。最初可能只是空的,并且 async 什么也得不到,但在调度后会更新。但是,由于期望未定义的 DNS,您会导致它出错。因此,为什么它在没有安全操作员的情况下会失败,但可以在安全的情况下工作。这些值稍后会更新为工作值。如果您将默认状态设置为具有 DNS 和一些假值的对象,它将起作用....试试吧! 【参考方案1】:在您的构造函数中,store
指的是整个应用程序状态,而不仅仅是network
。应该是
constructor(..., private store: Store<fromApp.AppState>)
您需要使用它访问它
this.dnsServers$ = this.store.select('network').map(network => network.dns);
另外,action.payload
是dns: ["6.7.7.7", "5.5.5.5"]
。当你在你的减速器中分配它时,你正在做dns: [action.payload]
,所以你最终会得到NetworkState
:
dns: [
dns: ["6.7.7.7", "5.5.5.5"]
]
如果您想在每次需要状态切片时减少构造函数中的逻辑,可以使用选择器:
import createFeatureSelector, createSelector from "@ngrx/store";
export const selectNetwork = createFeatureSelector<fromNetwork.NetworkState>('network');
export const selectNetworkDns = createSelector(selectNetwork, (state) => state.dns);
在构造函数中使用它:
constructor(private store: Store<fromApp.AppState>)
this.dnsServers$ = this.store.select(selectNetworkDns);
【讨论】:
我想通了。在我的模块中,我有StoreModule.forFeature('network', dnsReducer)
而不是StoreModule.forFeature('dns', dnsReducer)
,是的,我传递的是对象而不是列表,所以这也有帮助。我在状态“网络”下有多个减速器,所以我必须弄清楚如何构建它......
你可以传入一个对象:.forFeature('network', dns: dnsReducer, otherThing: otherThingReducer)
。也看看selectors。它将消除在.select()
之后调用.map()
的任何需要,只是为了获得一部分状态。
天哪,你是最棒的,这正是我想要的!但有一件事,你如何从网络切片访问 dns?谢谢!如果你想更新你的答案以包含它,我会把它标记下来
这是一个延迟加载的功能,所以我必须从网络状态访问它
感谢更新!唯一的问题是它是延迟加载的,所以我无法通过主应用程序状态访问它,它扩展了应用程序状态。以上是关于NgRx 无法从商店中选择的主要内容,如果未能解决你的问题,请参考以下文章