2012-11-23 8 views
7

In meiner Backbone-Anwendung habe ich ein Modell bestehend aus ein paar Untermodellen als Parameter.Aktualisieren von Backbone-Teilmodellen nach dem Abrufen/Speichern

Ich sehe es so:

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(), 
      }); 
    } 

}); 

Das Problem ist, wenn das Abrufen und Speichern. Wenn ich zum Beispiel die JSON-Antwort abrufe, enthält sie ein Objekt für info, ein Array für logins und ein Objekt für billing. Backbone weist sie automatisch als normale Parameter zu, was bedeutet, dass die Untermodelle mit einem einfachen Objekt überschrieben werden.

Meine aktuelle Lösung ist die fetch Methode für das Modell außer Kraft zu setzen, wie so:

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); 
    } 

dies ist jedoch nur für holen. Und da der aktualisierte Status des erstellten Modells beim Aufruf der Methode save() zurückgegeben wird, muss auch die Methode save() überschrieben werden.

Gibt es irgendwelche guten Ansätze, um dieses Problem zu lösen?

Vielleicht könnte das Überschreiben der set()-Methode funktionieren, aber ich befürchte, dass würde bedeuten, dass ich anfangen würde, von der Backbone-Codebasis abzukommen.

Ich dachte auch

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; 
    } 

wie so die Parse-Methode über die Verwendung, die einen Verweis auf das bereits aktualisierte Teilmodell schaffen würde.

+1

Ein möglicher Vorbehalt mit Dingen wie 'this.model.get ('info'). Set (response.info); response.info = this.model.get ('info'); 'ist das' x = m.get ('p'); x.set (...); m.set ('p', x) 'löst kein '' change '' Event aus (siehe die zweite Hälfte von http://stackoverflow.com/a/13369672/479863), ich bin mir nicht sicher, ob dies der Fall ist wird jedoch ein Problem mit Ihrem 'parse' sein. –

+0

Ich muss testen, wie das funktionieren würde, wenn ich Ereignisse an die Submodelle gebunden habe. So oder so kann ich leben, ohne Veränderungsereignisse auf dem Elternmodell zu haben, da es meistens verwendet wird, um alles zusammen zu strukturieren und die Ajax-Anfragen zu machen (mittels Backbone-Sync). – Daniel

Antwort

3

Normalerweise verwende ich parse für Untermodelle, wie in Ihrem zweiten Beispiel (obwohl Sie am Ende response zurückgeben müssen). Ich denke, das ist konzeptionell korrekt, da parse der geeignete Ort für die Umwandlung der serverseitigen Darstellung in eine clientseitige ist. Ich glaube, das sollte auch für save funktionieren, obwohl ich es nicht getestet habe, da parse auf die sichere Antwort auch aufgerufen wird.

Nach meiner Erfahrung ist das Überschreiben set nichts als Ärger - es neigt dazu, unbeabsichtigte Nebenwirkungen zu haben, und wird besser vermieden.

+0

'set' ist auch überraschend kompliziert, also, wenn Sie es überschreiben, werden Sie in der Regel nur zwicken Dinge und Punt auf die Standard-' set'. –

Verwandte Themen