2012-11-23 18 views
7

W mojej aplikacji Backbone mam model składający się z kilku pod-modeli jako parametrów.aktualizowanie podmodeli szkieletu po pobraniu/zapisaniu

zdefiniować ją tak:

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

}); 

Problem jest podczas pobierania i zapisywania. Podczas pobierania na przykład odpowiedź JSON obejmuje obiekt dla info, tablicę dla logins i obiekt dla billing. Szkielet automatycznie przypisuje je jako normalne parametry, co oznacza, że ​​podmodele są nadpisywane prostym obiektem.

Moje obecne rozwiązanie jest przesłonić metodę fetch dla modelu tak:

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

jest to jednak tylko do pobierania. A ponieważ zaktualizowany status utworzonego modelu jest zwracany podczas wywoływania metody save(), muszę również przesłonić metodę save().

Czy istnieją dobre metody rozwiązania tego problemu?

Być może przesłonięcie metody set() może zadziałać, jednak obawiam się, że oznaczałoby to, że zacznę błądzić z kodu podstawowego Kręgu.

Myślałem także o użyciu metody parse jak tak

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

które mogłyby stworzyć odniesienie do już zaktualizowanego modelu sub.

+1

Jedno z możliwych zastrzeżeń z takimi rzeczami jak 'this.model.get ('info') .set (response.info); response.info = this.model.get ('info'); 'jest tym' x = m.get ('p'); x.set (...); m.set ('p', x) 'nie wywoła zdarzenia' "change" '(zobacz drugą połowę http://stackoverflow.com/a/13369672/479863), nie jestem pewien czy to będzie problemem z twoim 'parse' chociaż. –

+0

Muszę przetestować, jak to będzie działać, jeśli mam zdarzenia związane z podmodelami. Tak czy inaczej mogę żyć bez zmiany wydarzeń w modelu nadrzędnym, ponieważ jest on używany głównie do struktury wszystko razem i zrobić żądania ajax (przy użyciu synchronizacji szkieletu). – Daniel

Odpowiedz

3

Generalnie używam parse dla podmodeli, tak jak w drugim przykładzie (należy pamiętać, że na końcu należy zwrócić response). Myślę, że jest to koncepcyjnie poprawne, ponieważ parse jest odpowiednim miejscem do przekształcenia reprezentacji po stronie serwera w stronę po stronie klienta. Wierzę, że to powinno zadziałać również dla save, chociaż nie testowałem tego, ponieważ parse jest wywoływane również przy odpowiedziach na zapis.

Z mojego doświadczenia wynika, że ​​nadpisywanie numeru set to tylko kłopot - ma niezamierzone skutki uboczne i lepiej go unikać.

+0

'set' jest również zaskakująco skomplikowany, więc jeśli go przesłonisz, zwykle będziesz chciał po prostu dostosować ustawienia i punt do standardowego" zestawu ". –

Powiązane problemy