类型错误:无法分配给打字稿中对象“[object Array]”的只读属性“0”

Amr*_*uta 6 javascript typescript ngrx angular

我正在研究 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));
        }),
    ),
  );
Run Code Online (Sandbox Code Playgroud)

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

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]'
Run Code Online (Sandbox Code Playgroud)

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

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]'
Run Code Online (Sandbox Code Playgroud)

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

以下是我的 ngOnchanges 方法

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

以下是主要的排序方法

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

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

fre*_*ett 90

对于那些使用 React/Redux 遇到此错误消息的人,可能是您试图直接改变状态,这是不允许的

\n

就我而言,我有这样的设置来获取 thunk 中的状态(简化):

\n
import store from "./myStore";\n\nconst state = store.getState();\nconst getItems = state => state.user.items;\nconst items = getItems(state);\n// \xe2\x86\x93 this blew up as it was attempting to manipulate `state`\nitems.sort((a, b) => a.order - b.order);\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
import store from "./myStore";\n\nconst state = store.getState();\nconst getItems = state => state.user.items;\n// \xe2\x86\x93 in my case items is an array, so I create a new array by spreading state here\nconst items = [...getItems(state)];\n// \xe2\x86\x93 which means we\'re not manipulating state, but just our `items` array alone\nitems.sort((a, b) => a.order - b.order);\n
Run Code Online (Sandbox Code Playgroud)\n

  • 是的,您需要克隆数组以创建一个全新的数组,否则任何更改都会影响基本状态对象 (2认同)

小智 28

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

arrayForSort = [...this.taskList]

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

  • 谢谢@Jan,这是因为 `.sort()` 编辑直接编辑变量。请参阅:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort (4认同)