【问题标题】:NgRx can't select from storeNgRx 无法从商店中选择
【发布时间】: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 和一些假值的对象,它将起作用....试试吧!

标签: angular rxjs store ngrx


【解决方案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?谢谢!如果你想更新你的答案以包含它,我会把它标记下来
  • 这是一个延迟加载的功能,所以我必须从网络状态访问它
  • 感谢更新!唯一的问题是它是延迟加载的,所以我无法通过主应用程序状态访问它,它扩展了应用程序状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-11
  • 2019-08-18
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
  • 1970-01-01
相关资源
最近更新 更多