javascript - TypeError: Không thể gán cho thuộc tính chỉ đọc '0' của đối tượng '[object Array]' trong typescript
Tôi đang làm việc với Angular 8.
- Tôi có một trang hiển thị một bảng. Bảng hiển thị dữ liệu từ một mảng đối tượng
taskListmà thành phần nhận được dưới dạng@Input(). - Tôi có một chức năng sắp xếp trên các cột của bảng này.
- Tôi cũng có một tùy chọn xóa trên mỗi hàng. Khi tôi nhấp vào tùy chọn xóa, nó thực hiện cuộc gọi API để xóa hàng đó và sau đó thực hiện một cuộc gọi khác để lấy mảng
tasklist. Đây là hiệu ứng đối với cùng một
@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));
}),
),
);
Vấn đề của tôi là chức năng sắp xếp hoạt động tốt khi tôi thực hiện lần tải trang đầu tiên. Nhưng nếu tôi xóa một dòng và sau đó lấy danh sách công việc sau khi xóa, tôi nhận được lỗi sau:
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]'
Theo thông báo lỗi, hàm sau trong mã của tôi gây ra lỗi
exchange(a, b) {
const temp = this.taskList[a];
this.taskList[a] = this.taskList[b]; //this line gives error
this.taskList[b] = temp;
}
Hàm này là phần của một đoạn mã sắp xếp sử dụng mảng tasklist và sắp xếp nó.
Luồng hoạt động là ngOnchanges(phát hiện thay đổi trong mảng taskList) gọi --> this.taskChange('export_name', 'asc') dựa trên một số điều kiện gọi --> this.exchange(a, b)
Dưới đây là phương thức ngOnchanges của tôi
ngOnChanges(changes: SimpleChanges) {
if (this.taskList !== null && this.taskList !== undefined) {
this.taskChange('export_name', 'asc');
}
}
Dưới đây là phương pháp sắp xếp chính
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;
}
}
}
}
Tôi không chắc chính xác điều gì đang gây ra lỗi này khi mảng thay đổi lần thứ hai. Tôi đã thử nhiều cách nhưng không cái nào hoạt động. Theo những gì tôi tìm thấy trên mạng, điều này có thể xảy ra vì tôi đang cố gắng thay đổi một mảng nhận được như @Input. Nhưng đoạn mã trên, vốn thay đổi mảng 'tasklist', hoạt động khi tải trang lần đầu. Và chỉ ngừng hoạt động khi mảng thay đổi. Có ai có thể giúp tôi không?
Câu trả lời #1
Hãy thử tạo một bản sao của mảng trước khi thử sắp xếp nó. Ví dụ như sử dụng toán tử spread.
arrayForSort = [...this.taskList]
Sau đó, sau khi sắp xếp, bạn có thể gán lại nó cho trường taskList
Câu trả lời #2
Đối với những người gặp vấn đề này kèm theo thông báo lỗi khi sử dụng React/Redux, có thể bạn đang cố gắng thay đổi trực tiếp state mà điều này là không được phép.
Trong trường hợp của tôi, tôi đã có thiết lập này để lấy trạng thái trong một thunk (đơn giản hóa):
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);
Điều này đã được sửa cho tôi bởi:
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);
