2015-05-29 8 views
6

In EmberData ruft der Aufruf model.save() auf, dass das Modell über den vorhandenen Adapter beibehalten wird. Wenn der Adapter einige Daten (z. B. JSON von einer API) zurückgibt, wird das Modell mit diesen Daten aktualisiert.EmberData Einstellwert verhindert zukünftige automatische Ladevorgänge von Daten nach dem Speichern des Modells.

Ich bin über eine Sequenz gestolpert, wo dies nicht wahr ist.

In einem Gutscheinsystem für einen Kassenvorgang wird ein voucherCode auf einem order Modell eingegeben. Wenn ein 'Anwenden' Knopf gedrückt wird, wird die Bestellung über order.save() gespeichert und der Gutschein wird somit an den Server gesendet.

Wenn der Gutscheincode gültig ist, wird ein voucherValue Feld mit einer Nummer ausgefüllt. Wenn der Gutscheincode ist ungültig ein 422 Fehler wird mit einem Standard-errors Objekt zurückgegeben, wie pro http://emberjs.com/api/data/classes/DS.Errors.html

Nun, hier ist, wo die Dinge schief gehen. Wenn ein Code eingegeben wird, der eine voucherValue von 300 zurückgibt, berechnet eine Controller-Eigenschaft den Rabatt.

Wenn der Benutzer aus irgendeinem Grund einen ungültigen Code eingibt, wird wie oben beschrieben ein Fehler zurückgegeben. Der Server entfernt den Rabatt und setzt die voucherValue-0

Da die Fehlerantwort enthält nicht die aktualisierten Daten in den catch der save wir es manuell aktualisieren.

order.save().then(function() { 

}).catch(function (error) { 

    order.set('voucherValue', 0); 
}); 

Die discountcomputed property wird auf die Einstellung der voucherValue wie erwartet aktualisiert. Die Überprüfung des Bestellmodells zeigt jedoch, dass order._data.voucherValue immer noch der ursprüngliche Wert 300 aus dem ersten gültigen Gutscheincode ist - da EmberData nicht weiß, dass dieser Wert auf dem Server beibehalten wird.

Wenn wir dann einen gültigen Gutscheincode eingeben, der ein voucherValue von 300 zurückgibt (das gleiche wie es ursprünglich war) die discount berechnete Eigenschaft wird nicht neu berechnet.

Es scheint, Ember überprüft die zurückgegebenen Datenwerte gegen order._data und da es keinen Unterschied gibt keine Eigenschaften Neuberechnungen auslösen.

Ich habe verschiedene Workarounds ausprobiert, konnte aber nichts finden, das zuverlässig funktioniert.

Frustrierend scheint es keine zuverlässige Möglichkeit zu geben, auf die zurückgegebenen Daten zuzugreifen und die voucherValue manuell aus den zurückgegebenen Daten festzulegen. Auch wenn die zurückgegebenen Daten einen Wert für voucherValue setzen folgendes gilt:

order.save().then(function (savedOrder) { 

    savedOrder.get('voucherValue') === 0; //true 

}).catch(function (error) { 
    order.set('voucherValue', 0); 
}); 

Wenn jedoch ein anderer Gutschein nach einem ungültigen Gutschein eingegeben und die voucherValue unterscheidet (etwa 450) alles wie erwartet funktioniert.

Ist das ein Fehler in EmberData? Gibt es eine bekannte Problemumgehung? Ich bin offen für Vorschläge und bereit, alles zu versuchen, bevor ich versuche und überarbeite, wie dieses gesamte System implementiert wird.

+0

Bitte ändern Sie den Wortlaut des Titels/Frage, wenn Sie können, ich weiß, was ich gestellt habe, ist ziemlich schrecklich. – Binarytales

+0

Ich bin mir nicht ganz sicher, aber ich glaube, ich hatte dieses Problem einmal ... Ich musste den http-Response-Code auf 204 ändern. Kein Inhalt, denke ich ... – enspandi

+0

Ich kann Ihr Szenario nicht replizieren. Sie sagen das Nachdem Sie versucht haben, einen Gutscheinwert von 300 zu speichern, einen Fehler vom Server erhalten und dann den Gutscheinwert auf 0 setzen (in Ihrem Catch), wenn Sie ihn dann erneut auf 300 setzen, berechnet die berechnete Eigenschaft nicht neu. Für mich tut es das. – jmurphyau

Antwort

0

Dieses Stück Code scheint ein Problem zu sein:

order.save().then(function (savedOrder) { 
    savedOrder.get('voucherValue') === 0; //true 
}).catch(function (error) { 
    order.set('voucherValue', 0); 
}); 

Die catch Funktion ist ein Proxy auf das Versprechen der Fang. Allerdings erwarten Versprechen normalerweise ein zweiter Parameter an die then Funktion übergeben werden, wie folgt aus:

order.save().then(function (savedOrder) { 
    savedOrder.get('voucherValue') === 0; //true 
}, function (error) { 
    order.set('voucherValue', 0); 
}); 

Diese zweite Funktion stellt den reject Weg des resolve/reject Paar durch die Promise verwendet. Siehe: http://emberjs.com/api/data/classes/DS.Model.html#method_save

+0

Aus meiner Lektüre der Dokumentation für Promises mit einem 'catch 'ist funktional gleichbedeutend mit der Übergabe des 'reject'-Handlers als zweites Argument an' then 'http://emberjs.com/api/classes/RSVP.Promise.html#method_catch – Binarytales

+1

Also hast du meinen Vorschlag versucht oder gehst du streng nach deiner Interpretation der Dokumente? –

+0

BTW, die "catch" -Funktion doc sagt: 'catch ist einfach Zucker für dann (undefined, onRejection), was es genauso macht wie der Catch-Block einer try/catch-Anweisung.So verkettet man ein' then() ' zum bestehenden 'then()' wenn das Sinn macht. Es ist nicht funktional gleichbedeutend mit der Übergabe des 'reject'-Handlers als zweites Argument an das erste' then' –

0

Wenn der Server soll model.voucherValue werden Einstellung, dann müssen Sie stoppen sie auf den Clients. Die Einstellung auf dem Client kann den beabsichtigten Status des Datensatzes beeinträchtigen, während Ember Data versucht, es in dem Adapter zu materialisieren.

ich denke, es kann ein bisschen, indem Sie Ihre Eigenschaftsdefinition gelöst werden:

discount: function() { 
    if (this.get('model.errors.length') > 0) { 
    return 0; 
    } 
    var discount = this.get('model.voucherValue'); 
    // some calculation 
    return discount; 
}.property('model.voucherValue', 'model.errors.length') 

oder etwas ähnliches, je nach Anwendungsfall.

+0

Dies ist etwas, das ich in Betracht gezogen habe, aber ich konnte nicht sehen, wie Embers eingebautes Fehlersystem * und * return verwendet werden der aktualisierte Wert ('Gutscheinwert = 0') in der Serverantwort. – Binarytales

+0

Wenn auf dem Server ein Fehler auftritt, sollten Sie außer dem Fehler nichts an den Client zurückgeben. Der Status des Servers sollte erst dann an den Client übertragen werden, wenn er wieder gültig ist - und Sie können nicht nur Annahmen über die Werte auf dem Server treffen, weshalb ich "Rabatt" als Zwischenwert vorschlage das macht für den Benutzer Sinn. – mpowered

Verwandte Themen