Angular 对象数组中对象的NgRx更新属性

Angular 对象数组中对象的NgRx更新属性,angular,typescript,rxjs,Angular,Typescript,Rxjs,我的商店中当前有一个对象数组。我想更新给定传入对象的该对象的单个属性 状态 export interface ApplicationState { ... allNavGroups: INavGroup[] | null; } 减速器 on(ApplicationActions.toggleCollapseNavGroup, (state, group: INavGroup ) => { const navGroup = state.allNavGroups.find

我的商店中当前有一个对象数组。我想更新给定传入对象的该对象的单个属性

状态

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 };
  })
然而,这导致:

错误类型错误:无法添加已折叠的属性,对象不可扩展

看了之后,我试着这样做,但问题是一样的:

const navGroups = [ ...state.allNavGroups ];
const navGroup = navGroups.find( g => g.groupId === group.groupId);
navGroup.collapsed = !navGroup.collapsed;
return { ...state, allNavGroups: navGroups };
我见过一些线程以不同的方式更新数组中的对象,但似乎有很多代码来完成一件简单的事情。在其他线程中,我看到您必须替换对象,而不是更新它。当我试着这样做时,它似乎起了作用。但是,这需要添加更多的逻辑,以确保数组的顺序与以前相同

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

更新如果我遍历数组中的每个对象并对其进行分解,它就会工作。这看起来像是一个黑客

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

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

对于你的情况,我会:

  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-映射创建了一个新数组(ram中的不同位置),因此我们正在以不变的方式更新数组

2-我们正在扩展对象并创建副本(ram中的不同位置),因此我们正在以不变的方式更新内部对象

3-我们正在使用第二个贴图创建一个新数组,并更改对象的一个键。可能没有必要散布
navGroup
并加固倒塌的房产,但我们还是做到了。这可能是你可以尝试的东西


至于为什么这样做,我相信这有助于提高性能和时间旅行调试。如果以后在应用程序中以可变方式更改数组中某个对象的此属性,则通过devtools中的redux存储将使其看起来好像所有以前的状态都有此不准确的更改(内存泄漏)。

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

对于你的情况,我会:

  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-映射创建了一个新数组(ram中的不同位置),因此我们正在以不变的方式更新数组

2-我们正在扩展对象并创建副本(ram中的不同位置),因此我们正在以不变的方式更新内部对象

3-我们正在使用第二个贴图创建一个新数组,并更改对象的一个键。可能没有必要散布
navGroup
并加固倒塌的房产,但我们还是做到了。这可能是你可以尝试的东西


至于为什么这样做,我相信这有助于提高性能和时间旅行调试。如果以后在应用程序中以可变方式更改数组中某个对象的此属性,则通过devtools中的redux存储将使其看起来好像所有以前的状态都有此不准确的更改(内存泄漏)。

有趣。我明天会试试看是否有效。谢谢你的解释。这基本上就是我在更新中描述的。但是,由于它是有效的,并且您描述了实际发生的情况,我会给您答案。我有一个类似于OP的情况,我想在一个数组中更新一个对象,该数组是父对象的一部分(也在一个数组中)。这非常有效,并描述了实际发生的情况。谢谢有趣。我明天会试试看是否有效。谢谢你的解释。这基本上就是我在更新中描述的。但是,由于它是有效的,并且您描述了实际发生的情况,我会给您答案。我有一个类似于OP的情况,我想在一个数组中更新一个对象,该数组是父对象的一部分(也在一个数组中)。这非常有效,并描述了实际发生的情况。谢谢你的更新非常有用。谢谢你的更新非常有用。谢谢