2013-06-06 11 views
8

Ciao ninja Backbone,Backbone anche dopo codice di risposta 200

Questa è la mia prima volta con Backbone - quindi per favore scusa la mia ness "niubbo". Nella mia funzionalità (parte di un'app più grande), ho un Backbone View vA, supportato da un modello mA (come dovrebbe essere) e il lato server è in Spring MVC che ha annotato i metodi del controller Spring con @RequestBody e @ResponseBody. Jackson lavora perfettamente con Spring.

Ora, in app,

Backbone.Model 
|_ BaseModel (custom base model for our app) 
    |_ mA (my model) 

mA ha il proprio endpoint e Backbone chiama con successo che quando si effettua una richiesta PUT per esempio, quando chiamo save() da un gestore di eventi pulsante di invio da View vA in questo modo:

this.model.save ({

  success : function(){ 

        alert('Request submitted successfully'); 


      }, 

      error : function(){ 
       alert('Something awful happened.'); 
      } 

});

nostro BaseModel ha il seguente: metodo di controllo

define([], function() { 



window.BaseModel = Backbone.Model.extend({ 
...... 


}); 

onSyncError : function(model, response) { 
     switch (response.status) { 
     case 403: 
     [...//some more code ] 
     default: 
      alert(bundle.getDefault('HTTP_RESP_OTH') + response.status); 
     } 
    }, 

    onSyncSuccess : function(model, response) { 
     alert('Sync done! '); 
    }, 

    sync : function(method, model, options) { 
     options.error = this.onSyncError; 
     Backbone.sync.call(this, method, model, options); 
     ....//some more stuff.  
    }, 

} 

Primavera:

@RequestMapping(value="/resource/xyz/{id}.json", method = RequestMethod.PUT, consumes  = {"application/json"} 
, produces = {"application/json"}) 
@ResponseBody 
public Map<String,String> methodX(@RequestBody XyzDTO xyzDTO){ 
.... 
map.put("msg", "success"); 

return map; 
} 

Inoltre, proprio prima di fare il risparmio chiamare, ho modificare gli attributi di un paio modello, dal momento che il DTO lato server ha una struttura diversa come questa:

this.model.unset("abc",{ silent: true }); 
this.model.set({ abc: {id : "2",xyz:{ ... //more code }); 

Il problema è, chiamare save() genera un PUT richiede e chiama con successo il gestore di endpoint Spring, ma ottengo un codice di risposta 200 (che è quello che mi aspetto), ma quando rintraccio la chiamata con Firebug, entra nel metodo onSyncError e mi dà un messaggio di errore (a causa della caso "predefinito" in esso).

Il documento Backbone dice: "Quando si restituisce una risposta JSON, inviare gli attributi del modello che sono stati modificati dal server e devono essere aggiornati sul client". Bene, non ho bisogno di aggiornare il modello sul lato client, è uno degli ultimi schermi e devo solo dire all'utente di un successo/errore e reindirizzare a una pagina principale/dashboard.

Ho letto un po 'di più, e sembra che il codice 200 come risposta non è sufficiente - potrebbero esserci errori di analisi JSON che causano il fallimento della sincronizzazione.

Ho controllato la risposta in Firebug, e la risposta JSON assomiglia a "" msg ":" Success "}.

Quindi, cosa potrebbe andare storto?

+1

io non sono sicuro se questo potrebbe causare il problema, ma non ho avuto problemi prima con il fatto che 'Backbone .Model.save() 'richiede effettivamente di mettere i tuoi dati di salvataggio come primo argomento, in questo modo:' model.save (model.toJSON(), {success: function() {}, error: function() {}); Mi sono imbattuto in problemi con questo in passato, dove ho avuto strani errori solo perché ho dimenticato che devi passare esplicitamente i dati che desideri salvare/pubblicare. Potrebbe fare un tentativo. – brettjonesdev

+0

Grazie per il tuo tempo. Ma non ha aiutato. Ora, ottengo questo in Firebug quando ritorna la risposta: TypeError: a is undefined ... funzione bi (a, b, d) {var e = b.dir, f = d && b.dir === "parentNode", g = u ++; ... – trishulpani

risposta

1

Grazie per il vostro tempo.Sono stato finalmente in grado di aggirare il problema usando $ .ajax per fare la richiesta PUT, bypassando così l'intera cosa Backbone sync. Il mio gestore di successo nel callback ajax gestisce la risposta e non ci sono più errori di sincronizzazione (poiché non viene chiamato comunque) :)

+0

Nessun problema. Non sono sicuro che aggirare il problema chiamando direttamente $ .ajax sia la soluzione migliore, ma qualsiasi cosa funzioni per te. Puoi anche controllare [questo thread] (http://stackoverflow.com/questions/6394108/how-should-server-respond-to-backbone-sync?rq=1) che risponde alla domanda su come il Server deve rispondere a 'model.save()'. – brettjonesdev

9

Backbone.Model.save() si aspetta che la risposta dal server sia un hash aggiornato dei valori del modello. Se la risposta è del tipo {"msg":"Success"}, Backbone potrebbe non riuscire a sincronizzarsi con il modello. Fondamentalmente, interpreta la risposta JSON HTTP 200 come attributi del modello e tenta di sincronizzare il modello di conseguenza.

Si potrebbe provare o 1) Effettuare la strada del controller Primavera restituisce una risposta modello di JSON-ified, 2) Restituisce una pianura di 200 con un corpo risposta vuota o 3) scrivere un parse metodo personalizzato che cerca risposte con il formato {"msg":"Success"} e risponde in modo diverso.

+3

un corpo di risposta vuoto chiamerà ancora il gestore degli errori, una risposta di ''{}'' non sarà se – robertjlooby

0

Condividerò la mia esperienza con lo stesso problema; modello base personalizzato e chiamando model.save e nessun evento di successo attivato.

Il mio problema era con una funzione di set personalizzato nel modello base che non restituiva "questo".

Se sbirciare il codice sorgente spina dorsale per il modello-save troverete questo frammento:!

options.success = function(resp) { 
    // Ensure attributes are restored during synchronous saves. 
    model.attributes = attributes; 
    var serverAttrs = model.parse(resp, options); 
    if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs); 
    if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) { 
     return false; 
    } 
    if (success) success(model, resp, options); 

    model.trigger('sync', model, resp, options); 
    }; 

Il model.set (serverAttrs, opzioni) non è riuscito nel mio caso e la funzione salva restituito falso prima di attivare qualsiasi evento.

Forse questo non era il problema, ma si spera che sarà aiutare qualcun altro là fuori ...

Problemi correlati