NgRx 更新对象数组中对象的属性 [英] NgRx Update property of object in array of objects

查看:58
本文介绍了NgRx 更新对象数组中对象的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的商店中目前有一组对象.给定传入的对象,我想更新该对象的单个属性.

I have an array of objects currently in my store. I want to update a single property of that object given a passed in object.

状态

export interface ApplicationState {
  ...
  allNavGroups: INavGroup[] | null;
}

减速器

  on(ApplicationActions.toggleCollapseNavGroup, (state, group: INavGroup ) => {
    const navGroup = state.allNavGroups.find( g => g.groupId === group.groupId);
    navGroup.collapsed = !navGroup.collapsed;
    return { ...state };
  })

然而,这会导致:

ERROR TypeError: 无法添加已折叠的属性,对象不可扩展

ERROR TypeError: Cannot add property collapsed, object is not extensible

在看到这个GitHub问题后,我尝试这样做方式,但同样的问题:

After seeing this GitHub issue, I tried doing it this way instead, but same issue:

const navGroups = [ ...state.allNavGroups ];
const navGroup = navGroups.find( g => g.groupId === group.groupId);
navGroup.collapsed = !navGroup.collapsed;
return { ...state, allNavGroups: navGroups };

我已经看到了一些关于更新数组中对象的不同方式的线程,但是做一件简单的事情似乎需要很多代码.在其他线程中,我看到您必须替换对象,而不是更新它.当我尝试这样做时,它似乎有效.但是,这需要添加更多逻辑以确保数组的顺序与以前相同.

I have seen a few threads on different ways to update an object in an array, but it seems like a lot of code to do a simple thing. In other threads, I saw that you have to replace the object, not update it. When I tried that, it seemed to work. However, that requires more logic to be added to make sure the order of the array is the same as it once was.

是否有一种简单的方法可以仅更新 Store 中的对象数组中的对象的属性?

Is there a simple way to update just a property on an object within an array of objects that is in the Store?

更新 如果我遍历数组中的每个对象并对其进行解构,它就可以工作.这似乎是一个黑客.

Update If I iterate through each object in the array and destructure it, it works. This seems like a hack.

const navGroups = state.allNavGroups.map(g => ({ ...g }));
const navGroup = navGroups.find( g => g.groupId === group.groupId);
navGroup.collapsed = !navGroup.collapsed;
return { ...state, allNavGroups: navGroups };

推荐答案

根据我的理解,对于通过引用存储的属性(数组和对象),即使它们彼此嵌套,您也必须不可变地改变状态.

From my understanding, you have to mutate the state immutably for properties that are stored by reference (arrays and objects) even if they are nested inside each other.

所以对于你的情况,我会这样做:

So for your case, I would do:

  return {
    ...state,                        // 1
    allNavGroups: state.allNavGroups.map(navGroup => ({...navGroup})) // 2
                                    .map(navGroup => { // 3
                                        if (navGroup.groupId === group.groupId) {
                                          return {
                                            ...navGroup,
                                            collapsed: !navGroup.collapsed,
                                          } else {
                                           return navGroup;
                                          }
                                        }
                                     })
  };

1 - 地图创建了一个新数组(内存中的不同位置),因此我们负责以不可变的方式更新数组.

1 - the map creates a new array (different location in ram), so we are taking care of updating the array in immutable way.

2 - 我们正在传播对象并创建一个副本(在 ram 中的不同位置),因此我们负责以不可变的方式更新内部对象.

2 - we are spreading the object and creating a copy (different location in ram), so we are taking care of updating the inner object in an immutable way.

3 - 我们正在使用第二个映射创建一个新数组并更改对象的键之一.可能没有必要传播 navGroup 并添加折叠的属性,但我们仍然这样做了.这可能是您可以尝试的东西.

3 - we are creating a new array with the 2nd map and changing one of the object's keys. It might not be necessary to spread navGroup and tack on the collapsed property but we did it nonetheless. This could be something for you to experiment with.

至于为什么这样做,我相信它有助于提高性能并有助于时间旅行调试.如果您稍后在应用程序中以可变方式更改数组中对象的此属性,则通过 devtools 中的 redux 存储将使之前的所有状态都具有此更改,这是不准确的(内存泄漏).

As to why it is done this way, I believe it helps with performance and helps with time travel debugging. If you were to change this property of an object in the array later in the application in a mutable way, going through the redux store in the devtools will make it as if all previous states had this change which is inaccurate (memory leak).

这篇关于NgRx 更新对象数组中对象的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆