2017-01-31 4 views
0

Ich habe eine Komponente mit einer Schaltfläche Hinzufügen, die zur Datenbank gehen wird, einen neuen Datensatz hinzufügen und dann die Daten des Observablen aktualisieren. Die Funktion zum Hinzufügen des neuen Datensatzes ist eine Promise, die aufgelöst wird, sobald der neue Datensatz hinzugefügt wurde. Während die Komponente auf die Datenbank zugreift, möchte ich die Schaltfläche Hinzufügen ausblenden, bis der neue Datensatz hinzugefügt wurde. Die Vorlage und Komponente sehen etwa wie folgt:Verzögerte Reaktion auf Klickereignis

Vorlage:

<table> 
... 
</table> 

<button (click)="addRow()" *ngIf="!addingRow">Add New</button> 

Komponentenklasse (Typoskript):

export class AuctionComponent { 
    addingRow: boolean = false; 

    addRow() { 
    this.addingRow=true; 
    console.log('Adding Row'); 
    this.salesSvc.addBid() 
     .then(()=> { 
     this.addingRow = false; 
     console.log('finished'); 
     }); 
    } 
} 

Das Versprechen, den neuen Datensatz hinzufügen löst in etwa ein zweite. Dies ist, was ich würde passieren würde denken:

  • Klicken Sie auf Hinzufügen Knopf
  • {Taste verschwindet}
  • „Hinzufügen Row“ zeigt in der Konsole nach oben
  • {warte eine Sekunde für das Versprechen zu lösen }
  • {Taste erscheint wieder}
  • "fertig" zeigt

Hier in der Konsole nach oben was tatsächlich passiert:

  • Klicken Sie auf Hinzufügen Schaltfläche
  • „Hinzufügen Row“ zeigt in der Konsole nach oben
  • {eine Sekunde lang warten, bis das Versprechen zu lösen}
  • „fertig“ erscheint in der Konsole
  • {Taste verschwindet kurz & erscheint wieder}

ich habe versucht, mit ngZone.run(), ChangeDetectorRef .markForChec k() & .detectChanges() und setTimeout(). Ich habe auch mit ChangeDetectionStrategy von Standard & OnPush herum gespielt. Was vermisse ich?

aktualisiert

So das Versprechen zu erreichen und um die Daten zu Feuerbasis zu speichern. Etwas damit zu tun, das Versprechen im Firebase zu lösen, scheint dies zu halten.

änderte ich die Komponente nur das Versprechen, ein Teil davon zu testen:

export class AuctionComponent { 
    addingRow: boolean = false; 

    addRow() { 
    this.addingRow=true; 
    console.log('Adding Row'); 
    // this.salesSvc.addBid() 
    this.promise() 
     .then(()=> { 
     this.addingRow = false; 
     console.log('finished'); 
     }); 
    } 

    promise() { 
    return new Promise((resolve, reject) => { 
     setTimeout(resolve, 2000); 
    }); 
    } 
} 

Dadurch die Taste so wie ich erwartet verhalten macht.

Die addBid Methode im Dienst sieht wie folgt aus (this.af ist AngularFire):

addBid(sale: ISale) { 
    return this.af.database.list(`sales/${sale.year}/bids`) 
     .push({lot: null, price: 0, description: ''}); 
    } 

Also dachte ich, dass vielleicht mit dem Feuerbasis Geschmack versprechen etwas geschieht, so wickelte ich das Ganze in meinem eigenes Versprechen:

addBid(sale: ISale) { 
    return new Promise((resolve, reject) => { 
     this.af.database.list(`sales/${sale.year}/bids`) 
     .push({lot: null, price: 0, description: ''}) 
     .then(() => resolve()) 
     .catch(() => reject()); 
    }); 
    } 

Aber wieder bekomme ich immer noch die verzögerte Antwort. Gibt es etwas in Firebase/angularfire2, das dazu führt, dass das Repaint nicht passiert?

+0

versuchen

refactor

+0

Getestet Ihren Code, und für mich gearbeitet wie sollte ...? – Alex

+0

@CleanCrispCode Guter Vorschlag ... Ich habe das versucht, aber ich bekomme die gleichen Ergebnisse. – jloosli

Antwort

0

Was Sie tun können, ist, wenn Sie die Antwort vom Server erhalten speichern Sie es in einer Variablen und machen Sie eine andere Methode erhalten, die wahr oder falsch zurückgibt abhängig von der Länge der Daten, die Sie erhalten. Wenn Sie also die Daten haben, haben Sie die Länge der Daten, in diesem Fall geben Sie true zurück, andernfalls false. Binden Sie diese Methode an die Schaltfläche.

zweite Option: Anfangs setzen Sie die Variable als wahr (wenn die Schaltfläche geklickt wurde), das ist richtig. Nun können Sie in der get-Methode diese Variable als false/true (abhängig von der Logik zum Ausblenden/Anzeigen) zurückgeben, wenn Sie die Datenlänge haben.

Ich denke, das sollte in Ihrem Fall funktionieren.

0

Für was es wert ist, war ich in der Lage, dies zum Funktionieren zu bringen, indem Sie das Versprechen Teil von addRow in setTimeout(). Ich bin mir immer noch nicht sicher, warum das nötig ist oder warum es funktioniert, also würde ich gerne etwas Rückmeldung oder Richtung in diesem Bereich bekommen.

addRow() { 
    this.addingRow = true; 
    setTimeout(() => { 
     this.salesSvc.addBid(this.sale) 
     .then(() => { 
      this.addingRow = false; 
     }); 
    }, 0);