2017-10-13 147 views
0

我正在做一个非常简单的NgRx实现,现在只是做一个组件的get。数据根据Redux Devtool在有效负载中传递,但我似乎无法通过异步管道访问它。NgRx无法从商店中选择

Devtool:

redux dev tool state redux dev tools image payload

---更新----

的问题是,当我在TS文件访问该片,我得到的错误

''network''类型的参数不能分配给类型为 的参数''start''。

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; 
    } 
} 
+0

尝试设置的dnsserver = this.store.select的定义( 'DNS')getDns之外()。如果您使用的是类型,请将类型设置为Obseravble for dnsServer。 – deek

+0

getDns()在ngOninit()中被调用,所以我不关心它是否在外面。我最终会输入observable,但那不是解决问题 – FussinHussin

+0

我想我知道。返回的有效载荷对象可能与订阅获取然后立即设置的值不同。可能最初只是空的,异步没有任何回应,但稍后会在调度后更新。但是,由于预计未定义DNS,导致它出错。因此,为什么它没有安全操作员而失败,但却安全地工作这些值稍后更新为工作值。 如果您将默认状态设置为具有DNS和某些假值的对象,它将起作用....尝试一下! – deek

回答

2

在你的构造,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); 
} 
+0

我想通了。在我的模块中,我有'StoreModule.forFeature('network',dnsReducer)'而不是'StoreModule.forFeature('dns',dnsReducer)'',我是传递对象而不是列表,所以这也有帮助。我在状态“网络”下有多个reducer,所以我必须弄清楚如何构造... – FussinHussin

+1

您可以传递一个对象:'.forFeature('network',{dns:dnsReducer,otherThing:otherThingReducer })'。另请看[选择器](https://github.com/ngrx/platform/blob/master/docs/store/selectors.md)。它将删除任何需要在'.select()'后面调用'.map()'来得到状态的片段。 – cdbajorin

+0

哦,男人,你是最好的,这正是我所期待的!但有一点,你如何从网络分片访问DNS?谢谢!如果你想更新你的答案,那么我将把它标记下来 – FussinHussin