Website-Suche

javascript - Angular 2: Wie erkennt man Änderungen in einem Array? (@Input-Eigenschaft)


Ich habe eine übergeordnete Komponente, die ein Array von Objekten mit einer Ajax-Anfrage abruft.

Diese Komponente hat zwei untergeordnete Komponenten: Eine von ihnen zeigt die Objekte in einer Baumstruktur und die andere rendert ihren Inhalt in Tabellenform. Die übergeordnete Komponente übergibt das Array über eine @input-Eigenschaft an ihre Kinder, und sie zeigen den Inhalt korrekt an. Alles wie erwartet.

Das Problem tritt auf, wenn Sie ein Feld innerhalb der Objekte ändern: Die Kindkomponenten werden über diese Änderungen nicht informiert. Änderungen werden nur ausgelöst, wenn Sie das Array manuell seiner Variablen erneut zuweisen.

Ich bin es gewohnt, mit Knockout JS zu arbeiten, und ich muss einen Effekt erzielen, der dem von observableArrays ähnlich ist.

Ich habe etwas über DoCheck gelesen, aber ich bin mir nicht sicher, wie es funktioniert.

Antwort #1

OnChanges-Lifecycle-Hook wird nur ausgelöst, wenn sich die Instanz der Eingabeeigenschaft ändert.

Wenn Sie überprüfen möchten, ob ein Element im Eingabearray hinzugefügt, verschoben oder entfernt wurde, können Sie IterableDiffers innerhalb des DoCheck-Lifecycle-Hooks wie folgt verwenden:

constructor(private iterableDiffers: IterableDiffers) {
    this.iterableDiffer = iterableDiffers.find([]).create(null);
}

ngDoCheck() {
    let changes = this.iterableDiffer.diff(this.inputArray);
    if (changes) {
        console.log('Changes detected!');
    }
}

Wenn Sie Änderungen an Objekten innerhalb eines Arrays erkennen müssen, müssen Sie alle Elemente durchlaufen und KeyValueDiffers auf jedes Element anwenden. (Sie können dies parallel zur vorherigen Überprüfung tun).

Besuchen Sie diesen Beitrag für weitere Informationen: Änderungen an Objekten innerhalb eines Arrays in Angular2 erkennen

Antwort #2

Sie können immer eine neue Referenz auf das Array erstellen, indem Sie es mit einem leeren Array zusammenführen:

this.yourArray = [{...}, {...}, {...}];
this.yourArray[0].yourModifiedField = "whatever";

this.yourArray = [].concat(this.yourArray);

Der obige Code wird die Array-Referenz ändern und es wird den OnChanges-Mechanismus in den Kindkomponenten auslösen.

Antwort #3

Lies den folgenden Artikel, verpasse nicht veränderliche vs. unveränderliche Objekte.

Das Hauptproblem ist, dass du Array-Elemente veränderst, während die Array-Referenz gleich bleibt. Und die Angular2-Änderungserkennung überprüft nur die Array-Referenz, um Änderungen zu erkennen. Wenn du das Konzept unveränderlicher Objekte verstehst, wirst du verstehen, warum du ein Problem hast und wie man es löst.

Ich verwende in einem meiner Projekte den Redux-Store, um solche Probleme zu vermeiden.

https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

Antwort #4

Sie können IterableDiffers verwenden

Es wird von *ngFor verwendet

constructor(private _differs: IterableDiffers) {}

ngOnChanges(changes: SimpleChanges): void {
  if (!this._differ && value) {
     this._differ = this._differs.find(value).create(this.ngForTrackBy);
  }
}

ngDoCheck(): void {
  if (this._differ) {
    const changes = this._differ.diff(this.ngForOf);
    if (changes) this._applyChanges(changes);
  }
}

Verwandte Artikel