ngrx/store не показывает обновленные значения формы
Мне нужно ввести 2 входных значения, которые показывают использование пространства хранения в мегабайтах (used_space и Остальное_пространство) через форму и показать введенные значения из ngrx/Store. Каждый раз при отправке формы показываются новые значения, а старые обновляются. Проблема в том, что пользовательский интерфейс всегда показывает значения по умолчанию (used_space и Остальное_пространство), и я не знаю, правильна ли моя архитектура, так как я новичок в ngrx/store.
Модель (creation.model.ts):
export interface Usage {
used_space: number;
remaining_space: number;
}
Действия (use.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;
Редуктор (use.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>
Я не вижу никакого результата, и я не знаю, что не так.
2 ответа
Проблема заключается в вашем 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);
}
Плюс, пока вы обновляете объект как единое целое в своем редукторе, я считаю, что вам не нужно Object.assign()
тоже. Вы можете напрямую вернуть action.payload
как это новое государство.
Я думаю, что проблема заключается в селекторе.
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;
}
}