如何更新NGRX相关数据?

问题描述 投票:0回答:1

我有两个模型,一对多关系:

export interface GroupModel {
  id: number;
  name: string;
  userIds?: number[];
}
export interface UserModel {
  id: number;
  name: string;
  groupId?: number;
}

问题是,当我用效果更新其中任何一个时,更改不会反映在相应的关联中:

groups.effects.ts

updateGroup$ = createEffect(() =>
  this.actions$.pipe(
    ofType(GroupsActions.updateGroup),
    concatMap(({ group }) =>
      this.groupsService.update(group).pipe(
        map(() =>
          GroupsAPIActions.groupUpdatedSuccess({
            update: { id: group.id, changes: group },
          })
        ),
        catchError((error) =>
          of(GroupsAPIActions.groupUpdatedFail({ message: error }))
        )
      )
    )
  )
);

users.effects.ts

updateUser$ = createEffect(() =>
  this.actions$.pipe(
    ofType(UsersActions.updateUser),
    concatMap(({ user }) =>
      this.usersService.update(user).pipe(
        map(() =>
          UsersAPIActions.userUpdatedSuccess({
            update: { id: user.id, changes: user },
          })
        ),
        catchError((error) =>
          of(UsersAPIActions.userUpdatedFail({ message: error }))
        )
      )
    )
  )
);

我的减速器更新方法如下所示:

on(
  GroupsActions.groupStation,
  (state) =>
    ({
      ...state,
      loading: true,
      errorMessage: '',
    })
),
on(GroupsAPIActions.groupUpdatedSuccess, (state, { update }) =>
  groupsAdapter.updateOne(update, {
    ...state,
    loading: false,
  })
),
on(
  GroupsAPIActions.groupUpdatedFail,
  (state, { message }) =>
    ({
      ...state,
      loading: false,
      errorMessage: message,
    })
)

总而言之,我们有以下模型:

groups: [
  { id: 1, name: "Group 1", userIds?: [1, 2] }
];
users: [
  { id: 1, name: "User 1", groupId: 1 }
  { id: 2, name: "User 2", groupId: 1 }
];

然后我调用调度方法,我们想要从组中删除用户 2:

this.store.dispatch(UserActions.updateUser({
    user: { id: 2, name: "User 2", groupId: undefined }
});

我希望第 1 组也从

userId
数组中删除
userIds

{ id: 1, name: "Group 1", userIds?: [1] }

实现这一目标的好方法是什么?是否有标准方法或者我需要编写代码来手动处理这个问题?

编辑:

我为

groupsReducer
手动编写了以下代码,但这对于如此琐碎的任务来说似乎有很多代码。

on(UsersAPIActions.userUpdatedSuccess, (state, { update }) => {
  const userId = +update.id;
  const newGroupId = update.changes.groupId;
  const allGroups = selectAll(state);

  console.log(update);
  // Find the group that contains the userId
  const groupToUpdate = allGroups.find((group: GroupModel) =>
    group.userIds.includes(userId)
  );

  const updateGroupChanges = {} as Partial<GroupModel>;

  // Group is found
  if (groupToUpdate) {
    // UpdatedUser has a group
    if (newGroupId) {
      // A: If the group is the same: do nothing
      if (groupToUpdate.id === newGroupId) return state;
      // B: If the group is different, remove the user from the old group and add it to the new one
      const oldGroupChanges = {
        userIds: groupToUpdate.userIds.filter(
          (id) => id !== newGroupId
        ),
      } as Partial<GroupModel>;
      const newGroupChanges = {
        userIds: [...groupToUpdate.userIds, newGroupId],
      } as Partial<GroupModel>;

      console.log(
        `Group ${groupToUpdate.id}: Moving user ${userId} to group ${newGroupId}`
      );

      return groupsAdapter.updateMany(
        [
          { id: groupToUpdate.id, changes: oldGroupChanges },
          { id: newGroupId, changes: newGroupChanges },
        ],
        { ...state }
      );
    }

    // UpdatedUser has no group: Remove group
    console.log(`Group ${groupToUpdate.id}: Removing user ${userId}`);

    updateGroupChanges.userIds = groupToUpdate.userIds.filter(
      (id) => id !== newGroupId
    );
  } else {
    // No group is found
    // UpdatedUser has no group: Do nothing
    if (!newGroupId) return state;

    // UpdatedUser has a group: Add user to a group
    const newGroup = selectGroupById(newGroupId)(state);
    if (!newGroup) {
      console.warn(
        `Group ${newGroupId}: Not found! Could not add user ${userId}`
      );
      return state;
    }

    console.log(`Group ${newGroupId}: Adding user ${userId}`);

    updateGroupChanges.userIds = [...newGroup.userIds, userId];
  }

  return groupsAdapter.updateOne(
    {
      id: newGroupId,
      changes: updateGroupChanges,
    } as Update<GroupModel>,
    { ...state } satisfies GroupsEntityState
  );
}),
angular typescript ngrx
1个回答
1
投票

为了更新这两个状态,reducers 将监听这两个操作来更新自己的状态。

例如。减少的小组将聆听

groupUpdatedSuccess
(就像现在一样),也会聆听行动
userUpdatedSuccess

这同样适用于用户减速器,它监听

userUpdatedSuccess
groupUpdatedSuccess
操作。

© www.soinside.com 2019 - 2024. All rights reserved.