【问题标题】:ngrx/store not showing the updated values of a formngrx/store 未显示表单的更新值
【发布时间】:2018-06-13 14:20:47
【问题描述】:

我需要通过表单输入 2 个输入值,以兆字节(used_space 和剩余空间)为单位显示存储空间的使用情况,并显示来自 ngrx/Store 的输入值。每次提交表单时,都会显示新值并更新旧值。问题是 UI 总是显示(used_space 和 remaining_space)的默认值,我不知道我的架构是否正确,因为我是 ngrx/store 的新手。

模型(usage.model.ts):

   export interface Usage {
      used_space: number;
      remaining_space: number;
    }

动作(usage.actions.ts):

export const EDIT_USAGE  = '[Usage] Edit';
...
export class EditUsage implements Action {
  readonly type = EDIT_USAGE
  constructor(public payload: Usage) {}
}
...
export type All = Reset | EditUsage;

减速器(usage.reducer.ts): 导出类型 Action = UsageActions.All;

/// Default app state
const defaultState: Usage = {
  used_space: 2,
  remaining_space: 3
}

/// Helper function to create new state object
const newState = (state, newData) => {
  return Object.assign({}, state, newData)
}

export function usageReducer(state: Usage = defaultState, action: Action) {
  switch(action.type) {
    case UsageActions.EDIT_USAGE:
      // return [...state, action.payload];
      return newState(state, { Usage: action.payload });
    case UsageActions.RESET:
      return defaultState;
    default:
      return state;
  }
}

在 app.component.ts 中:

  usage: Observable<Usage>

  constructor(private store: Store<AppState>) {
    this.usage = this.store.select('usage')
  }

  editUsage(used_space,remaining_space) {
    this.store.dispatch(new UsageActions.EditUsage({used_space:used_space , remaining_space:remaining_space}) )
  }

在 app.component.html 中:

<input type="text"  #used_space>
<input type="text"  #remaining_space>
<button (click)="editUsage(used_space.value,remaining_space.value)" >Edit Space</button>

<div *ngIf="usage | async as u">
  <h2>Used space: {{ u.used_space }}</h2>
  <h2>remaining space: {{ u.remaining_space }}</h2>
</div>

我没有看到任何结果,也不知道出了什么问题。

【问题讨论】:

  • 你在app.module.ts注册了reducer吗?
  • 是的,它已经注册了

标签: angular redux ngrx ngrx-store ngrx-effects


【解决方案1】:

问题出在你的reducer:

switch(action.type) {
  case UsageActions.EDIT_USAGE:
    return newState(state, { Usage: action.payload }); <<--------
}

您正在传递先前的状态和 new object with usage as a propertyObject.assign 所做的是:创建一个新对象,将先前的状态附加到它,附加一个全新的属性 Usage 并为其添加新的 store 值。这是新创建的对象的视图:

你可以直接通过payload来解决这个问题:

switch(action.type) {
  case UsageActions.EDIT_USAGE:
    return newState(state, action.payload);
}

Working Demo

另外,只要您在 reducer 中更新整个对象,我相信您也不需要 Object.assign()。您可以直接返回action.payload,因为它是新状态。

【讨论】:

  • 非常感谢您的提议,它就像一个魅力.. :)
  • 你的解决方案还是有问题:更换路由器后表格中输入的数据消失了。你知道这背后的原因吗?
  • 你可以试试this吗?
  • 我看到了链接,我会试试看。但我认为直接从 UI 组件访问服务是不安全的,中间应该有一种控制器(例如组件 .ts 文件),以便不暴露服务。反正我会试试的。
【解决方案2】:

我认为问题出在选择器上。

this.store.select('usage')

如果您的商店中有一个名为 usage 的对象,它将起作用。

例如:

const defaultState: AppState = {
  usage: {
    used_space: 2,
    remaining_space: 3
  }
}

所以你的代码应该是

// Default app state
const defaultState: AppState = {
  usage: {
    used_space: 2,
    remaining_space: 3
  }
}

export function usageReducer(state: AppState = defaultState, action: Action) {
  switch(action.type) {
    case UsageActions.EDIT_USAGE:
      return {
        ...state,
        usage: action.payload
      }

    case UsageActions.RESET:
      return defaultState;

    default:
      return state;
  }
}

【讨论】:

  • 感谢回复,但我已经在reducer中定义了默认值
  • app.component.ts 中接收到表单输入的值,但显示的值始终是默认值。请问这里有什么帮助吗?
  • 抱歉,我的回复有误。我会解释你的代码中存在不连贯性。 defaultState 应该是 AppState 类型。然后在一个对象内部使用。这是您的 EDIT_ACTION 内部的情况,返回是可以的。但 defaultState 不是。
  • 所以我创建了“add.state.ts”文件:'interface AppState {用法:用法; }' ,然后我将 AppState 导入减速器中。之后应用您建议的代码更改,对吗?
  • 我尝试了我上面提到的但仍然没有工作..你知道一个显示类似要求的例子:只更新一个包含 2 个值的对象而不需要收集对象?甚至我可以使用 2 个“数字”类型的变量(used_space 和剩余空间)而不将它们包装在一个对象中并通过 ngrx/store 更新它们吗?
猜你喜欢
  • 1970-01-01
  • 2017-04-15
  • 2022-04-25
  • 2021-04-25
  • 2018-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-30
相关资源
最近更新 更多