javascript - TypeError: Kann der schreibgeschützten Eigenschaft '0' des Objekts '[object Array]' in TypeScript nicht zuweisen
Ich arbeite an Angular 8.
- Ich habe eine Seite, die eine Tabelle anzeigt. Die Tabelle zeigt Daten aus einem Objektarray
taskList, das die Komponente als@Input()erhält. - Ich habe eine Sortierfunktion für die Spalten dieser Tabelle.
- Ich habe auch eine Löschoption in jeder Zeile. Wenn ich auf die Löschoption klicke, wird ein API-Aufruf ausgeführt, um die Zeile zu löschen, und dann ein weiterer Aufruf, um das
tasklist-Array abzurufen. Dies ist die Auswirkung, dass für dasselbe
@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));
}),
),
);
Mein Problem ist, dass die Sortierfunktion einwandfrei funktioniert, wenn ich sie beim ersten Laden der Seite ausführe. Aber wenn ich eine Zeile lösche und dann die Aufgabenliste nach dem Löschen abrufe, bekomme ich den folgenden Fehler:
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]'
Laut der Fehlermeldung erzeugt die folgende Funktion in meinem Code den Fehler
exchange(a, b) {
const temp = this.taskList[a];
this.taskList[a] = this.taskList[b]; //this line gives error
this.taskList[b] = temp;
}
Diese Funktion ist der Teil eines Sortiercodes, der das tasklist-Array verwendet und sortiert.
Der Ablauf ist ngOnchanges(erkennt Änderungen im taskList-Array) ruft auf --> this.taskChange('export_name', 'asc') basierend auf einer Bedingung ruft auf --> this.exchange(a, b)
Im Folgenden ist meine ngOnChanges-Methode
ngOnChanges(changes: SimpleChanges) {
if (this.taskList !== null && this.taskList !== undefined) {
this.taskChange('export_name', 'asc');
}
}
Im Folgenden wird die Hauptsortiermethode beschrieben
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;
}
}
}
}
Ich bin mir nicht sicher, was genau diesen Fehler verursacht, wenn sich das Array zum zweiten Mal ändert. Ich habe eine Menge Dinge ausprobiert, aber keiner davon hat funktioniert. Nach dem, was ich online gefunden habe, könnte dies passieren, weil ich versuche, ein als @Input empfangenes Array zu ändern. Aber der obenstehende Code, der das 'tasklist'-Array ändert, funktioniert beim initialen Laden der Seite. Und hört erst auf zu funktionieren, wenn sich das Array ändert. Könnte mir jemand helfen?
Antwort #1
Versuche, eine Kopie des Arrays zu erstellen, bevor du versuchst, es zu sortieren. Zum Beispiel durch Verwendung eines Spread-Operators.
arrayForSort = [...this.taskList]
Dann könnten Sie es nach dem Sortieren dem Feld taskList wieder zuweisen
Antwort #2
Für diejenigen, die auf dieses Problem mit dieser Fehlermeldung in React/Redux stoßen, könnte es sein, dass Sie versuchen, den Zustand direkt zu ändern, was nicht erlaubt ist.
In meinem Fall hatte ich diese Einrichtung, um den Zustand innerhalb eines Thunks zu erhalten (vereinfacht):
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);
Dies wurde für mich behoben durch:
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);
