【问题标题】:NgRx state add/update as array and keep in syncNgRx 状态添加/更新为数组并保持同步
【发布时间】:2019-12-31 05:23:15
【问题描述】:

如果需要添加多个对象,如何使用 ngrx 更新状态?

例如,在下面的示例中,一个用户可以与多个任务相关联。

目前,当所有任务都返回时,存储会更新两次,每次更新时,最后一个任务都会被一个新任务替换。这是预期的行为,但您将如何初始化一个数组并捕获更新以作为对象数组的状态并确保它保持同步

task.reducer.ts

import * as TaskActions from './task.actions';
import { Action, createReducer, on } from '@ngrx/store';
import { ITask } from '../../models/task';

export interface State {
  task: ITask | null;
  error: any;
}

const initialState: ITask = {
  basketTotal: 0,
  carePlanPrice: 0,
  category: null,
  completionDate: null
};

export const taskReducer = createReducer(
  initialState,
  on(TaskActions.getData, state => ({ ...state })),
  on(TaskActions.dataReceived, (state, payload) => ({ ...state, payload })),
  on(TaskActions.dataNotReceived, state => ({ ...state })),
  on(TaskActions.signOut, state => ({ ...state })),
  on(TaskActions.signOutSuccess, state => ({ ...state, ...initialState })),
);

export function reducer(state: ITask | undefined, action: Action) {
  return taskReducer(state, action);
}

task.effect.ts

  @Effect()
  getData$ = this.actions$.pipe(
    ofType(TaskActions.getData),
    switchMap(() => {
      return this.afs.collection<ITask>('tasks', ref =>
        ref.where('createdBy', '==', localStorage.getItem('uid'))).stateChanges().pipe(
      );
    }),
    mergeMap(actions => actions),
    map(action => {
      if (action.payload) {
        return TaskActions.dataReceived({ payload: TaskService.parseData(action.payload.doc.data()) });
      } else {
        return TaskActions.dataNotReceived();
      }
    })
  );

task.actions.ts

import { createAction, props } from '@ngrx/store';
import { ITask } from '../../models/task';

export const getData = createAction('[Task] Get Data');
export const dataReceived = createAction('[Task] Data Received', props<{ payload: Partial<ITask> }>());
export const dataNotReceived = createAction('[Task] Data Not Received');
export const signOut = createAction('[Task] Sign Out');
export const signOutSuccess = createAction('[Task] Sign Out Success');

更新:

我试过了

on(TaskActions.dataReceived, (state, payload) => 
  ({ 
      ...state, 
      tasks: [...state.tasks,  payload.payload ] 
  })),

结果如下:

我期待一个包含两个项目的数组:

task: [
  { ... }, { ... }
]

【问题讨论】:

    标签: javascript angular typescript google-cloud-firestore ngrx


    【解决方案1】:

    spread语法也可以用于数组创建一个克隆。

    on(TaskActions.dataReceived, (state, payload) => 
      ({ 
          ...state, 
          tasks: payload.condition ? [...state.tasks,  payload.newTask ] : []
      })),
    

    Spread syntax docs

    【讨论】:

    • 您好,感谢您的回复。这似乎不起作用
    • 您能否更明确地说明您要做什么,因为[...original, item],在原始数组的基础上附加了一个新数组
    • 我想根据从 Firestore 返回的数据同步存储,因此一旦检索到数据,用户要么得到一个空数组,要么得到 +n 个数组项。
    • 查看更新后的答案,您必须设置条件才能分配新任务
    • 谢谢。什么是 payload.newTask?
    猜你喜欢
    • 2022-06-18
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    相关资源
    最近更新 更多