2012-11-23 17 views
7

Nella mia applicazione Backbone ho un modello costituito da un paio di sotto-modelli come parametri.aggiornamento dei sottomodelli backbone dopo il recupero/salvataggio

mi definisco così:

app.Models.Account = Backbone.Model.extend({ 

    initialize : function() { 
     this.set({ 
       info  : new app.Models.Info(), 
       logins : new app.Collections.Logins(), 
       billing : new app.Models.Billing(), 
      }); 
    } 

}); 

Il problema è quando il recupero e il salvataggio. Quando recupero ad esempio, la risposta JSON include un oggetto per info, un array per logins e un oggetto per billing. Backbone li assegna automaticamente come parametri normali, il che significa che i sotto-modelli sono sovrascritti con un oggetto semplice.

La mia soluzione attuale è quella di sovrascrivere il metodo fetch per il modello in questo modo:

fetch: function(options) { 
     options = options ? _.clone(options) : {}; 
     var model = this; 
     var success = options.success; 
     options.success = function(resp, status, xhr) { 
     resp = model.parse(resp, xhr); 

     model.get('info').set(resp.info); 

     model.get('logins').reset(resp.logins); 

     model.get('billing').set(resp.billing); 

     if (success) success(model, resp); 
     }; 

     options.error = Backbone.wrapError(options.error, model, options); 
     return (this.sync || Backbone.sync).call(this, 'read', this, options); 
    } 

tuttavia questo è solo per andare a prendere. E poiché lo stato aggiornato del modello creato viene restituito quando si chiama il metodo save(), devo anche eseguire l'override del metodo save().

Esistono approcci validi per risolvere questo problema?

Forse l'override del metodo set() potrebbe funzionare, tuttavia temo che ciò significherebbe che avrei iniziato a deviare dal codice base Backbone.

Ho anche pensato di utilizzare il metodo parse in questo modo

parse : function (response) { 
     this.model.get('info').set(response.info); 
     response.info = this.model.get('info'); 

     this.model.get('logins').reset(response.logins); 
     response.logins = this.model.get('logins') 

     this.model.get('billing').set(response.billing); 
     response.billing = this.model.get('billing'); 

     return response; 
    } 

che creerebbe un riferimento al modello di sub già aggiornato.

+1

Un avvertimento possibile con cose come 'this.model.get ('info'). Set (response.info); response.info = this.model.get ('info'); 'è quel' x = m.get ('p'); x.set (...); m.set ('p', x) 'non innescherà un evento' 'change '' (vedi la seconda parte di http://stackoverflow.com/a/13369672/479863), non sono sicuro se questo sarà un problema con il tuo 'parse' però. –

+0

Devo verificare come funzionerebbe se avessi eventi legati ai sottomodelli. In ogni caso, posso vivere senza dover cambiare eventi sul modello principale poiché è principalmente usato per strutturare tutto insieme e fare richieste ajax (usando la sincronizzazione backbone). – Daniel

risposta

3

Generalmente utilizzo parse per i modelli secondari, come nel secondo esempio (sebbene si tenga presente che è necessario restituire response alla fine). Penso che questo sia concettualmente accurato, poiché parse è il luogo appropriato per trasformare la rappresentazione lato server in una lato client. Credo che questo dovrebbe funzionare anche per save, anche se non l'ho ancora testato, dal momento che parse è chiamato anche sulla risposta di salvataggio.

Nella mia esperienza, ignorare lo set non è altro che un problema: tende ad avere effetti collaterali indesiderati ed è meglio evitare.

+0

'set' è anche sorprendentemente complicato quindi, se si esegue l'override, di solito si desidera solo modificare le cose e puntare allo' set' standard. –

Problemi correlati