javascript - TypeError: Nelze přiřadit hodnotu pouze pro čtení vlastnosti '0' objektu '[object Array]' v TypeScriptu
Pracuji na Angular 8.
- Mám stránku, která zobrazuje tabulku. Tabulka zobrazuje data z pole objektů
taskList, které komponenta získává jako@Input(). - Mám funkci třídění na sloupcích této tabulky.
- Také mám na každém řádku možnost smazání. Když kliknu na možnost smazání, provede se volání API k odstranění řádku a potom další volání k načtení pole
tasklist. Toto má za následek, že pro stejné
@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));
}),
),
);
Můj problém je v tom, že funkce řazení funguje dobře při prvním načtení stránky. Ale pokud smažu řádek a pak načtu seznam úkolů po smazání, dostanu následující chybu:
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]'
Podle chybové zprávy následující funkce v mém kódu způsobuje chybu
exchange(a, b) {
const temp = this.taskList[a];
this.taskList[a] = this.taskList[b]; //this line gives error
this.taskList[b] = temp;
}
Tato funkce je součástí třídicího kódu, který používá pole tasklist a třídí ho.
Průběh je ngOnchanges(detekuje změnu v poli taskList) volá --> this.taskChange('export_name', 'asc') na základě nějaké podmínky volá --> this.exchange(a, b)
Následuje moje metoda ngOnChanges
ngOnChanges(changes: SimpleChanges) {
if (this.taskList !== null && this.taskList !== undefined) {
this.taskChange('export_name', 'asc');
}
}
Následující je hlavní metoda třídění
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;
}
}
}
}
Nejsem si jistý, co přesně způsobuje tuto chybu, když se pole změní podruhé. Zkoušel jsem spoustu věcí, ale žádná z nich nefungovala. Z toho, co jsem našel online, se to může dít proto, že se snažím měnit pole, které jsem obdržel jako @Input. Ale výše uvedený kód, který mění pole 'tasklist', funguje při prvním načtení stránky. Přestane fungovat až poté, co se pole změní. Mohl by mi někdo pomoci?
Odpověď č. 1
Zkuste vytvořit kopii pole před tím, než se jej pokusíte seřadit. Například pomocí operátoru rozbalení.
arrayForSort = [...this.taskList]
Poté po seřazení byste jej mohli přiřadit zpět do pole taskList
Odpověď č. 2
Pro ty, kteří se k tomuto problému dostanou s touto chybovou zprávou při používání React/Redux, může být problém v tom, že se pokoušíte přímo měnit stav, což není povoleno.
V mém případě jsem měl tuto konfiguraci pro získání stavu uvnitř thunk (zjednodušeně):
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);
To pro mě opravila:
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);
