ngrx / store未显示表单的更新值

时间:2018-06-13 14:20:48

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

我需要输入2个输入值,通过表单显示存储空间的使用情况(兆字节(used_space和remaining_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;

Reducer(usage.reducer.ts):     export type 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>

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

2 个答案:

答案 0 :(得分:3)

问题在于您的reducer

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

您正在通过之前的州和 new object with usage as a property Object.assign的作用是:创建一个新对象,将以前的状态附加到它,附加一个全新的属性Usage并添加新的存储值。这是新创建的对象的视图:

您可以直接通过payload解决此问题:

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

Working Demo

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

答案 1 :(得分:0)

我认为问题在于选择器。

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