2016-06-06 10 views
0

Ich habe das Gefühl, dass Angular 2 einige Dinge fehlen, die Angular 1 hatte, eines davon ist die $watch Funktion.Wie kann man Änderungen in einem Array von Objekten beobachten, ohne eine massive Verzögerung zu verursachen?

OnChanges und DoCheck sollen die $watch ersetzen, aber ich konnte nicht verwenden, um das gewünschte Ergebnis zu erhalten. OnChanges kann nicht auf Objekte hören, so dass es in diesem Szenario nicht von Nutzen ist, und während DoCheck den Job erledigt, verursacht es massive Verzögerung, da es scheint, Bananen zu gehen, sobald eine Änderung geschieht.

Hier habe ich eine Komponente, die eine Reihe von Kontrollkästchen hat, jedes Kontrollkästchen Umschalt bewirkt, dass ein Wert zu einem Array hinzugefügt wird, anstatt die Standard-true/false-Funktionalität.

Was muss ich aufpassen in dieser Komponente ist der isDisabled Zustand einer Checkbox, so dass jedes Mal ändert Ich brauche den isChecked Zustand des checkbox zu aktualisieren.

Wie ich schon sagte, es funktioniert, aber es hat 2-3 Sekunden Verzögerung auf jedem Kontrollkästchen umschalten, obwohl nur 5 Kontrollkästchen. Vorzugsweise möchte ich nicht, dass die Schleife jedes Mal ausgeführt wird, wenn Sie ein Kontrollkästchen aktivieren, sondern nur, wenn sich der Status eines Kontrollkästchens ändert.

BEARBEITEN: Mir wurde gesagt, ein Observable könnte hier den Job erledigen, aber ich kann keine Beispiele finden, die auf ein Array von Objekten wie diesem angewendet werden. Es muss auch manuell ohne Aufruf seiner next() Methode auszulösen, da es außerhalb Änderungen an dem Array zu hören hat, die in gesendet wird

EDIT 2:. Ich habe plunkr geschaffen, die nicht die Verzögerung nicht zeigt, wahrscheinlich, weil ich in meiner App andere Dinge habe, die die Verzögerung ebenfalls beeinflussen könnten. Der Plunkr zeigt jedoch deutlich, dass etwas falsch zu sein scheint, weil ich console.log(true) innerhalb der ngDoCheck()-Funktion einfüge, und es läuft eine Unmenge von Malen. Was nicht beabsichtigt sein kann, ist es wirklich merkwürdig.

Hier ist der plunkr: https://plnkr.co/edit/dJVnqbrredDyWTXNDzDK?p=preview

Wie kann ich das tun?

export class FormCheckboxMultipleComponent implements OnInit, DoCheck { 
    @Input() model: Array<any>; 
    @Output('modelChange') onModelChange: EventEmitter<any> = new EventEmitter(); 
    @Output() callback: EventEmitter<any> = new EventEmitter(); 

    constructor(private _globals: GlobalVariablesService) { 
    this.ns = _globals.ns; 
    } 

    ngOnInit() { 
    this.model = this.model || []; 
    } 

    ngDoCheck() { 

    for (let checkbox of this.checkboxes) { 

     if (checkbox.isDisabled) { 
     this.untoggle(checkbox); 
     } 
    } 
    } 

    findIndex(checkbox) { 

    return this.model.reduce(function(cur, val, index) { 

     if (val.name === checkbox.name && cur === -1) { 
     return index; 
     } 

     return cur; 
    }, -1); 
    } 

    addToModel(checkbox) { 
    this.model.push(checkbox); 
    } 

    removeFromModel(i) { 
    this.model.splice(i, 1); 
    } 

    toggle(checkbox) { 

    if (checkbox.isDisabled) { 
     return false; 
    } 

    let existingIndex = this.findIndex(checkbox); 

    if (existingIndex === -1) { 
     this.addToModel(checkbox); 
    } 
    else { 
     this.removeFromModel(existingIndex); 
    } 

    checkbox.isChecked = !checkbox.isChecked; 

    this.onModelChange.emit(this.model); 

    this.callback ? this.callback.emit() : false; 
    } 

    untoggle(checkbox) { 

    let existingIndex = this.findIndex(checkbox); 

    this.removeFromModel(existingIndex); 

    checkbox.isChecked = false; 

    this.onModelChange.emit(this.model); 
    } 
} 
+0

Sie konnten uns nur ein 'Observable' über Veränderungen statt oder zusätzlich zu dem Array Änderung zu informieren. Dies ist der Weg in Angular2, um teure Deep-Value-Comparonsons zu vermeiden. –

+0

@ GünterZöchbauer Ich habe Probleme zu verstehen, wie man Observable verwendet, obwohl ich unzählige Beispiele anschaue. Könnten Sie ein Beispiel geben, das in dieser Komponente funktionieren würde? Würde es wirklich zu schätzen wissen. – Chrillewoodz

+0

Vielleicht kommst du in https://github.com/angular/angular/issues/3406, ansonsten mit 5 Checkboxen sollte eine Verzögerung kaum messbar sein. –

Antwort

1

, die von this.onModelChange.emit(this.model); in this.untoggle(checkbox) in ngDoCheck verursacht wird. Dies ist eine perfekte Endlosschleife. this.onModelChange.emit(this.model); verursacht Änderungserkennung und daher ngDoCheck() zu laufen und die Schleife beginnt erneut.

Stellen Sie sicher, dass die Änderungserkennung keine Änderungserkennung verursacht. ngDoCheck wird durch Änderungserkennung aufgerufen und darf keine weitere Änderungserkennung aufrufen, sonst erhalten Sie eine Endlosschleife.

Plunker

+0

Ich habe gerade Änderungen in ngDoCheck vorgenommen und es ausgegeben und es verursacht diesmal keine Endlosschleife ... komisch. – Chrillewoodz

+0

Ich denke, dass dies auch näher untersucht werden müsste. –

+0

Ich machte einen Plunkr mit der aktualisierten Version, aber ich bekomme einige seltsame Zone Fehler: https://plnrk.co/edit/arROwxsFYraSbeAZCIYF?p=preview – Chrillewoodz

Verwandte Themen