2015-02-09 7 views
12

Nella mia app, un utente può creare un messaggio e inviarlo. Quando l'utente invia il messaggio, il messaggio viene creato con createRecord e il server risponde con 201 Creato se ha esito positivo.Ember Data ha record duplicati

Inoltre, l'utente può ricevere messaggi da altri utenti tramite una web-socket. Quando riceve un messaggio, lo sposto nel negozio con pushPayload.

var parsedData = JSON.parse(data); 
this.store.pushPayload('message', parsedData); 

Il problema è che, quando un utente invia un messaggio e lo salva, ma hanno anche indietro dal websocket, e anche se entrambi gli oggetti hanno lo stesso ID, il negozio finisce con messaggi duplicati.

Come posso dire al negozio che quando spingo o salvo qualcosa con lo stesso id di un elemento già esistente, dovrebbe sovrascriverlo?

+0

Secondo http://emberjs.com/api/data/classes/DS.Store.html#method_pushPayload dovrebbe aggiornare i record – Jakeii

+1

Lo fa, ma solo quando la risposta websocket è in ritardo. Sono sicuro che il problema è una condizione di gara. Trattare con runloop sembra aver risolto il problema, ma mi assicurerò prima di pubblicare la mia risposta. –

+0

Come hai detto, penso che il ciclo di esecuzione sia sospetto qui. Mi assicurerei che tu stia facendo 'Ember.run.next (function() {_this.store.pushPayload (....' così viene eseguito dopo che il record è inizialmente persistito. Nella mia esperienza, può anche essere multiplo eseguire loop, nel qual caso 'Ember.run.later' con un timeout arbitrariamente lungo lo confermerà nella risoluzione dei problemi – mpowered

risposta

3

L'unico metodo che ho trovato per evitare questo problema è quello di eseguire il mio aggiornamento a una nuova runloop. Se il ritardo in ms è sufficientemente lungo, il problema non si verificherà.

Sembra che ricevere l'aggiornamento dal websocket e la richiesta quasi allo stesso tempo crei una condizione di competizione in Ember Data.

+2

Posso confermare che questo bug esiste ancora in Ember Data 1.13.11. – bsegraves

+0

WTF, davvero ?? Come è questa una soluzione? –

+0

Non ho mai detto che fosse una soluzione. È più simile a una soluzione temporanea. –

3

semplicemente eseguire un controllo per verificare se il modello è già in negozio prima di aggiungere:

var parsedData = JSON.parse(data); 
if(this.store.hasRecordForId ('typeOfYourRecord', parsedData.id)){ 
    // logic you want to run when the model is already in the store 
    var existingItem = this.store.find('typeOfYourRecord', parsedData.id); 
    // perform updates using returned data here 
} else { 
    this.store.pushPayload('message', parsedData); 
} 
+2

Funziona solo quando dico al server di attendere un secondo prima di avvisare gli utenti. la notifica arriva troppo velocemente e il salvataggio non è stato completato. Accetterò la risposta se è l'unico modo, ma sono sorpreso che Ember Data consenta record duplicati, ci deve essere un modo per eseguire il push e l'override. metodo di aggiornamento, ma Ho avuto lo stesso problema. –