2015-05-29 10 views
6

In EmberData la chiamata model.save() causa la permanenza del modello tramite qualsiasi adattatore inserito. Se l'adattatore restituisce alcuni dati (come JSON da un'API), il modello viene aggiornato con tali dati.EmberData Il valore dell'impostazione impedisce futuri caricamenti automatici di dati dopo il salvataggio del modello

Mi sono imbattuto in una sequenza in cui questo non è vero.

In un sistema di voucher per un processo di checkout è inserito un voucherCode su un modello order. Quando viene premuto il pulsante "Applica", l'ordine viene salvato tramite order.save() e il buono viene quindi inviato al server.

Se il codice del buono è valido, il campo voucherValue viene popolato con un numero. Se il codice voucher non è valido, viene restituito un errore 422 con un oggetto standard errors come da http://emberjs.com/api/data/classes/DS.Errors.html

Ora, qui è dove le cose vanno male. Se viene inserito un codice che restituisce un voucherValue di 300, una proprietà del controllore calcola lo sconto.

discount: function() { 
    var discount = this.get('model.voucherValue'); 
    // some calculation 
    return discount; 
}.property('model.voucherValue') 

Se, per qualsiasi motivo, l'utente poi entra un codice non valido torniamo un errore come descritto sopra. Il server rimuove lo sconto e imposta il voucherValue-0

Come la risposta di errore non contiene i dati aggiornati nel catch del save aggiorniamo manualmente.

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

}).catch(function (error) { 

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

Il discountcomputed property viene aggiornato come previsto sull'impostazione del voucherValue. Tuttavia, l'ispezione del modello di ordine mostra che è ancora il valore originale del 300 dal primo codice voucher valido - poiché EmberData non sa che questo valore è persistente sul server.

Se poi entriamo un codice voucher valido che restituisce un voucherValue di 300 (lo stesso come era in origine) la discount proprietà calcolata non viene ricalcolato.

Sembra che Ember stia verificando i valori dei dati restituiti rispetto a order._data e poiché non vi è alcuna differenza non causa alcun ricalcolo di proprietà.

Ho provato soluzioni alternative diverse ma non sono riuscito a trovare qualcosa che funzioni in modo affidabile.

Frustrantemente non sembra essere un modo affidabile per accedere ai dati restituiti e impostare manualmente il valore voucherValue dai dati restituiti. Anche se i dati restituiti imposta un valore per voucherValue seguenti condizioni:

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

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

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

Tuttavia, se un buono diverso viene inserita dopo un buono valido e il voucherValue è diverso (diciamo 450) tutto funziona come previsto.

Si tratta di un bug in EmberData? C'è un modo per ovviare al problema. Sono aperto a suggerimenti e pronto a provare qualsiasi cosa prima di provare e riprogettare come viene implementato l'intero sistema.

+0

Si prega di modificare la formulazione del titolo/domanda se è possibile, so che cosa ho messo è abbastanza orribile. – Binarytales

+0

Non ne sono del tutto sicuro, ma penso che una volta ho avuto questo problema ... Ho dovuto cambiare il codice di risposta http a 204 No Content Immagino ... – enspandi

+0

Non riesco a replicare il tuo scenario .. Tu dici che dopo aver provato a salvare un VoucherValue di 300, ottenendo un errore dal server e impostando voucherValue su 0 (nel tuo catch), se lo imposti a 300 ancora la proprietà calcolata non ricalcola .. per me lo fa .. – jmurphyau

risposta

0

Questo bit del codice sembra essere un problema:

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

La funzione catch è un proxy per le catture effettuate dalla promessa. Tuttavia, le promesse di solito si aspettano un secondo parametro da passare alla funzione then, in questo modo:

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

Questa seconda funzione rappresenta il percorso reject del resolve/reject coppia utilizzata dal Promise. Vedi: http://emberjs.com/api/data/classes/DS.Model.html#method_save

+0

Dalla mia lettura della documentazione di Promises che usa un 'catch 'è funzionalmente equivalente al passaggio del gestore di' reject' come secondo argomento a 'then 'http://emberjs.com/api/classes/RSVP.Promise.html#method_catch – Binarytales

+1

Quindi hai provato il mio suggerimento o stai andando rigorosamente dalla tua interpretazione dei documenti? –

+0

BTW, la funzione "catch" doc dice: "catch è semplicemente zucchero per allora (non definito, onRejection) che lo rende lo stesso del blocco catch di un'istruzione try/catch". Quindi stai concatenando un 'then()' all'esistente 'then()' se questo ha un senso. Non è funzionalmente equivalente passare il gestore 'reject' come secondo argomento al primo' then' –

0

Se il server deve impostare model.voucherValue, è necessario interrompere l'impostazione sul client. Impostarlo sul client può interferire con lo stato previsto del record mentre Ember Data sta cercando di materializzarlo nell'adattatore.

penso che può essere risolto cambiando la definizione di proprietà un po ':

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') 

o qualcosa di simile, a seconda del caso d'uso.

+0

Questo è qualcosa che avevo considerato ma non sono stato in grado di vedere come usare il sistema di errore incorporato di Ember * e * return il valore aggiornato ('voucherValue = 0') nella risposta del server. – Binarytales

+0

Se c'è un errore sul server, non si dovrebbe restituire nulla al client a parte l'errore. Lo stato del server non deve essere trasferito al client fino a quando non diventa di nuovo valido e non si possono semplicemente formulare ipotesi su quali saranno i valori sul server, motivo per cui sto suggerendo "sconto" come valore intermedio questo ha senso per l'utente. – mpowered

Problemi correlati