【问题标题】:TypeError: Cannot assign to read only property '0' of object '[object Array]' in typescriptTypeError:无法在打字稿中分配给对象“[object Array]”的只读属性“0”
【发布时间】:2020-11-22 18:12:11
【问题描述】:

我正在研究 Angular 8。

  1. 我有一个显示表格的页面。该表显示来自对象数组taskList 的数据,组件将其作为@Input() 获取。
  2. 我对这个表的列有排序功能。
  3. 我在每一行也有一个删除选项。当我单击删除选项时,它会调用 api 来删除行,然后再调用来获取 tasklist 数组。 这是相同的效果
  @Effect()
  DeleteTask$: Observable<Action> = this.actions$.pipe(
    ofType(importActions.DELETE_TASK),
    switchMap(params =>
      this.globalService
        .deleteTask(params)
        .mergeMap(deleteSuccess => {
          return from([
            new importActions.DeleteTaskSuccess(deleteSuccess),
            new importActions.LoadTaskList(),
          ]);
        })
        .catch((error, caught) => {
          return Observable.of(new GlobalError(error));
        }),
    ),
  );

我的问题是当我在第一页加载时排序功能工作正常。但是如果我删除一行然后在删除后获取任务列表,我会收到以下错误:

ERROR Error: Uncaught (in promise): TypeError: Cannot assign to read only property '0' of object '[object Array]'
TypeError: Cannot assign to read only property '0' of object '[object Array]'

根据错误消息,我的代码中的以下函数给出了错误

  exchange(a, b) {
    const temp = this.taskList[a];
    this.taskList[a] = this.taskList[b]; //this line gives error
    this.taskList[b] = temp;
  }

此函数是排序代码的一部分,它使用tasklist 数组并对其进行排序。
流量为ngOnchanges(detects change is taskList array) calls --&gt; this.taskChange('export_name', 'asc') based on some condition calls --&gt; this. exchange(a, b)

以下是我的 ngOnchanges 方法

ngOnChanges(changes: SimpleChanges) {
    if (this.taskList !== null && this.taskList !== undefined) {
      this.taskChange('export_name', 'asc');
    }
  }

以下是主要的排序方式

  async taskChange(value, taskOrder) {
    this.sortOrder = taskOrder;
    this.selectedValue = value;
    const expr = {
      asc: (a, b) => a > b,
      desc: (a, b) => a < b,
    };
    for (let i = 0; i < this.taskList.length; i++) {
      for (let j = i + 1; j < this.taskList.length; j++) {
        switch (value) {
          case 'export_name':
            if (
              expr[this.sortOrder](this.taskList[i].name, this.taskList[j].name)
            ) {
              this.exchange(i, j);
            }
            break;
          case 'file_type':
            let type1;
            let type2;
            type1 = this.exportType.transform(this.taskList[i].code, []);
            type2 = this.exportType.transform(this.taskList[j].code, []);
            if (expr[this.sortOrder](type1, type2)) {
              this.exchange(i, j);
            }
            break;
        }
      }
    }
  }

当数组第二次更改时,我不确定究竟是什么导致了这个错误。我尝试了很多东西,但都没有奏效。从我在网上发现的情况来看,这可能会发生,因为我试图改变作为@Input 接收的数组。但是上面的代码,它改变了“tasklist”数组,在初始页面加载时起作用。并且仅在数组更改时停止工作。有人可以帮帮我吗?

【问题讨论】:

  • 这不是 ngrx 的正确范例。在选择器内部进行排序。

标签: javascript angular typescript ngrx


【解决方案1】:

在尝试排序之前尝试创建数组的副本。就像使用扩展运算符一样。

arrayForSort = [...this.taskList]

然后在排序后您可以将其分配回taskList 字段

【讨论】:

【解决方案2】:

对于那些使用 React/Redux 遇到此错误消息的人,可能是您尝试直接更改状态 which isn't allowed

在我的例子中,我有这个设置用于在 thunk(简化)中获取状态:

import store from "./myStore";

const state = store.getState();
const getItems = state => state.user.items;
const items = getItems(state);
// ↓ this blew up as it was attempting to manipulate `state`
items.sort((a, b) => a.order - b.order);

这是通过以下方式为我解决的:

import store from "./myStore";

const state = store.getState();
const getItems = state => state.user.items;
// ↓ in my case items is an array, so I create a new array by spreading state here
const items = [...getItems(state)];
// ↓ which means we're not manipulating state, but just our `items` array alone
items.sort((a, b) => a.order - b.order);

【讨论】:

  • 所以我们必须直接从getState()中复制!非常感谢!
  • 是的,您需要克隆数组以创建一个全新的数组,否则任何更改都会影响基本状态对象
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 2022-11-10
  • 2023-03-13
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 2019-02-08
相关资源
最近更新 更多