在 Angular NGXS 中访问数组内的嵌套对象

Access Nested Object Inside Array in Angular NGXS

我已经在我的Angular 应用程序中成功实现了删除评论功能。我现在的问题是评论的点赞功能。我如何实现类似的功能。我有变量 is_liked 来确定它是否喜欢。 value = 0 表示不喜欢,value = 1 表示喜欢。 请在此处

查看我的 stackblitz link

PLS CLICK THIS LINK

onLikeComment(data: Comment) {
    this.store.dispatch(new LikeComment(data)).subscribe();
  }

@Action(LikeComment)
  likeComment(
    ctx: StateContext<PostStateModel>,
    { payload }: LikeComment
  ) {
    if (payload.is_liked === 1) {
      payload.is_liked = 0;
    } else {
      payload.is_liked = 1;
    }
    const state = ctx.getState();
    ctx.setState(
      patch({
        post: {
          ...state.post,
          comments: [
            ...state.post.comments,
            updateItem<any>(name => name === payload.id, payload)
          ]
        }
      })
    );
  }

您可以按如下方式处理 'like' 函数。

ctx.setState(
      patch({
        post: {
          ...state.post,
          comments: this.getUpdatedComments(state, payload)
        }
      })
    );

getUpdatedComments(state, payload): any {
      let comments = [];
      state.post.comments.forEach((cmt) => {
          if (cmt.id === payload.id) {
              cmt = Object.assign({}, cmt);
              cmt.is_liked = payload.is_liked === 1 ? 0 : 1;
          }
          comments.push(cmt);
      });
      return comments;
  }

这是更新后的演示 - https://stackblitz.com/edit/ngxs-delete-like-dek3s1

您的代码中存在的主要问题是 updateItem 状态运算符的使用。此运算符需要分配给您传递给 patch 运算符的对象中的字段。

patch({
  field1: 'someValue',
  comments: updateItem<Comment>(
    comment => comment.id === 0,
    {id: 0, text: 'This is a nice post!', is_liked: 1}
  )
})

updateItem Reference

我发现您的操作处理程序存在的第二个问题是您没有正确使用补丁运算符。此运算符只允许将值分配给要更改的字段,如 StateContext.patchState.

我会将您的代码更改为:

  @Action(LikeComment)
  likeComment(
    ctx: StateContext<PostStateModel>,
    { payload }: LikeComment
  ) {
    const isLiked = payload.is_liked === 1 ? 0 : 1;

    ctx.setState(
      patch({
        // Apply patch on the post to only update the comments field
        post: patch({
          // Apply updateItem to make the operator only update the item that matches the condition
          comments: updateItem<Comment>(
            comment => comment.id === payload.id,
            // Apply a patch on the found comment to only change the is_liked field.
            patch({is_liked: isLiked}))
        })
      })
    );
  }

希望这是有道理的。这是我对 SO 的第一个回答 :)

这是updated stackblitz

我是 NGXS 的新手,但我能够通过使用内置运算符来做到这一点。在这个阶段,我认为不需要添加不变性工具,例如 Immer。

这是我的数据:

const jobs = [
  {
    id: 0,
    tasks: [
      {
        id: 0,
        status: 'To Do',
        ...
      }
  ... 
  }
]

这是更新嵌套对象的操作:

  @Action(SetJob)
  setTask(ctx: StateContext<JobsStateModel>, { payload }: SetJob) {
    ctx.setState(
      patch({
        jobs: updateItem((item: any) => item.status === payload.status, patch({ tasks: insertItem(payload, 1) })),
      })
    );
  }