【问题标题】:Cannot add property X, object is not extensible after ngrx 9 update无法添加属性 X,ngrx 9 更新后对象不可扩展
【发布时间】:2020-07-08 00:17:53
【问题描述】:

我遇到了类似的问题

无法添加属性 X,对象不可扩展

在使用 Ngrx 更新将我的 Angular 项目更新为 Angular 9 之后。当我将 Ngrxversion 回滚到 8 时,它工作正常。但我也需要使用 Angular 9 更新将其更新到 v9。当我将其添加为具有附加属性的材料表中的 datasource.data 时,就会发生这种情况。我认为额外的属性改变是一个原因。但是我从我们得到的新数组中创建了新数组,并使用 slice 进行了如下尝试。

 myDataArray.slice(0)

它也不起作用。

我在这里参考了 Ngrx 版本 8 到 9 的更改列表和迁移指南https://ngrx.io/guide/migration/v9

我发现 Angular 9 有一个与不变性相关的特殊变化。他们在那里定义了与动作、状态和可序列化性相关的不变性逻辑。我在https://ngrx.io/guide/store/configuration/runtime-checkshttps://ngrx.io/guide/store/configuration/runtime-checks 尝试了他们建议的解决 Ngrx V9 更新问题的方法

但这些对我不起作用。如果有人能解决这个问题,这真的很有帮助。提前谢谢..

错误堆栈跟踪..(我也使用了 matDataFlatner,这就是对象突变发生的地方)

app-error-handler.ts:30 TypeError: 无法添加属性级别,对象 不可扩展 在 MatTreeFlatener.defaultFlatenerTransform [as transformFunction] (tree-table-flattener-builder.ts:57) 在 MatTreeFlatener._flattenNode (flat-data-source.ts:58) 在 flat-data-source.ts:81 在 Array.forEach () 在 MatTreeFlatener._flattenChildren (flat-data-source.ts:78) 在 MatTreeFlatener._flattenNode (flat-data-source.ts:65) 在 flat-data-source.ts:92 在 Array.forEach () 在 MatTreeFlatener.flattenNodes (flat-data-source.ts:92) 在 MatTreeFlatDataSource.set (flat-data-source.ts:138)

【问题讨论】:

  • 您是否尝试过克隆来自商店的对象?假设 myDataArray 是通过选择器从存储中获取的,请尝试使用 myDataArray = JSON.parse(JSON.stringify(myDataArray)) 或任何其他深度克隆方法。
  • 如果您使用堆栈跟踪发布实际错误会有所帮助。这样可以更好地了解导致此问题的操作
  • @PierreDuc 我添加了堆栈跟踪。你能看看吗
  • @julianobrasil 非常感谢。那是有效的。有什么理由吗。?有没有其他好的深度克隆机制...
  • 好吧,在一个完美的世界里,您应该尝试使用您发布的与运行时检查相关的链接上的一种技术来解决问题。无论如何,如果你真的需要坚持深度克隆,你可以试试npmjs.com/package/fast-copy

标签: angular redux ngrx angular9


【解决方案1】:

我在这里参考 Ngrx 版本 8 到 9 的更改列表和迁移指南

https://ngrx.io/guide/migration/v9

我发现 Angular 9 有一个与不变性相关的特殊变化。他们在那里定义了与动作、状态和可序列化性相关的不变性逻辑。我在这里尝试了他们建议的解决 Ngrx V9 更新问题的方法

https://ngrx.io/guide/store/configuration/runtime-checks

您可以进行以下更改,


@NgModule({
  imports: [
  StoreModule.forRoot(reducers, {
    runtimeChecks: {
      strictStateImmutability: false,
      strictActionImmutability: false,
    },
  }),
 ],
})
export class AppModule {}

@ngrx/store ships with five (5) built-in runtime checks. Try disabled all checks

【讨论】:

    【解决方案2】:

    您应该深度克隆 myDataArray,因为它是通过选择器从商店中出来的。保持存储中数据的不变性是 redux 模式的重要组成部分,如果您修改 myDataArray,您将直接更改存储中的数据(取决于您的选择器,它可能是相同的数据 => 参考到存储中的数组)。

    您可以在尝试对其进行任何更改之前执行myDataArray = JSON.parse(JSON.stringify(myDataArray))

    有更有效的方法可以深度克隆对象,例如使用fast-copy

    import copy from 'fast-copy';
    
    ...
    
    myDataArray = copy(myDataArray);
    

    【讨论】:

      【解决方案3】:

      您可以使用 lodash 库中的 cloneDeep 函数来深度克隆对象并避免错误:

      import {cloneDeep} from 'lodash';

      const clonedData = cloneDeep(myDataArray);

      然后,您可以添加属性或所有您想要克隆的数据对象。

      问候!

      【讨论】:

        猜你喜欢
        • 2020-06-23
        • 1970-01-01
        • 2019-08-29
        • 1970-01-01
        • 2021-02-02
        • 2021-10-13
        • 1970-01-01
        • 1970-01-01
        • 2020-09-03
        相关资源
        最近更新 更多