2012-02-09 17 views
16

Ho un modello di backbone. Con model.set() posso impostare un valore locale, con model.save() posso salvare l'intero modello sul server.backbone.js: Esiste un cambiamento dall'ultimo salvataggio del server?

Come faccio a sapere se c'è stata una modifica dall'ultimo salvataggio del server che indica che la versione locale è sporca.

model.isNew(); funziona solo se il modello non è mai stato salvato sul server.

+0

il dirty bit non è la stessa cosa di controllare se è cambiato (a seconda della definizione). Es: il modello potrebbe inizialmente essere isGood: true, passa a isGood: false, quindi torna a isGood: true. In questo caso, il bit dirty potrebbe essere attivo, ma il modello non viene effettivamente modificato. Va bene? – Matt

risposta

16

EDIT: Questa risposta è stata scritta prima della versione 1.0 di Backbone. A partire dalla versione Backbone corrente (1.2.2) hasChanged non riflette più le modifiche "dall'ultimo salvataggio". Invece, riflette le modifiche "dall'ultimo set".


Ascoltare per modificare gli eventi o controllare hasChanged.

Se il modello è stato modificato, è possibile risparmiare sulle modifiche. Puoi anche collegare il tuo metodo di salvataggio al fuoco quando si verifica l'evento di cambiamento.

Se non si desidera salvare le modifiche, impostare una proprietà per il modello sporco e cancellarlo quando si salva esplicitamente.

Qualcosa di simile:

change: function(){ 
    this.dirty = true; 
} 

save: function(){ 
    // do your save 
    if(success){ 
     this.dirty = false; 
    } 
} 

isDirty: function(){ 
    return this.dirty 
} 
+1

Ma c'è una versione senza un dirty-bit? – knub

+0

@knub Cosa intendi? Backbone non fornisce questo. Forniscono l'evento 'change' e il metodo' hasChanged'. Questo è un modo per implementare un sistema di lazy-save-only-if-dirty-data. Idealmente, chiameresti 'model.save()' quando riceverai l'evento 'change'. In questo modo se perdi il cliente non perdi le loro modifiche. – tkone

+0

Ho pensato che ci fosse qualche funzionalità nascosta nel Backbone-Core che potrebbe fornirmi tali informazioni. Voglio dire, Backbone HA queste informazioni, semplicemente non me lo offre. E il bit sporco è sporco, lo sai;). Ma ok, ovviamente non c'è altra soluzione (ancora?). – knub

4

opzione alternativa è quella di impostare tutti gli aggiornamenti per gli aggiornamenti 'silenziosi', e poi raccogliere le modifiche quando si desidera sincronizzare:

// Updates 
myModel.set({foo: 'bar'}, {silent: true}); // Does not fire a 'changed' event 
myModel.set({foobar: 'barfoo'}, {silent: true}); 

// Sync 
if (myModel.hasChanged()) { 
    console.log(myModel.changedAttributes()); // {'foo':'bar', 'foobar':'barfoo'} 
    _.each(myModel.changedAttributes(), function(value, key) { 
    console.log(key+' used to be '+myModel.previous(key)+', but now is '+value); 
    } 
    myModel.save(); 
} 
+0

non sembra funzionare con backbone 1.1.2 – user116293

5

sto lavorando con CouchDB e Couch ha un attributo _rev che cambia dopo ogni salvataggio. Ho risolto il problema della "dal-last-server-save" inserendo il seguente codice nei modelli inizializzare funzione:

 initialize : function() { 
     this.on('change',function(){ 
      if(this.hasChanged('_rev')) { 
       this.isSaved = true; 
      }else{ 
       this.isSaved = false; 
      } 
     },this); 
     } 
0

Tutte le risposte che suggeriscono l'ascolto per le modifiche (con eventi) sono corrette a meno che non si passa {silenzioso: vero} opzione. In tal caso, è necessario sovrascrivere il metodo set predefinito per salvare gli attributi che sono stati modificati e ripristinare tale elenco dopo aver chiamato il metodo di salvataggio.

MidnightLightning's answer non è corretta. Se si chiama il metodo di impostare due volte, quindi changedAttributes torneranno solo gli attributi che ha cambiato da chiamata ultimo insieme - è nella documentazione Backbone:

changedAttributesmodel.changedAttributes([attributes])

recuperare un hash di attributi solo del modello che hanno cambiato da quando il ultimo set, o falso se non ce ne sono.

Nel mio caso ho risolto il problema con questo codice:

(function(_, Backbone) { 
    'use strict'; 

    var _set = Backbone.Model.prototype.set, 
    _save = Backbone.Model.prototype.save; 

    _.extend(Backbone.Model.prototype, { 
    set: function(key, val, options) { 
     var options = this._getOptions(key, val, options), 
     toReturn = _set.call(this, key, val, options); 
     if(!_.isUndefined(options) && options.silent && !!this.changedAttributes()) { 
     this.silentChanges = _.extend([], this.silentChanges); 
     [].push.apply(this.silentChanges, _.keys(this.changedAttributes())); 
     } 
     return toReturn; 
    }, 
    save: function(key, val, options) { 
     var options = this._getOptions(key, val, options), 
     toReturn = _save.call(this, key, val, options); 
     if(!_.isUndefined(options) && options.triggerSilents) { 
     this.triggerSilentChanges(); 
     } 
     return toReturn; 
    }, 
    unset: function(key, options) { 
     if(!_.isUndefined(options) && options.silent) { 
     this.silentChanges = _.extend([], this.silentChanges, _.keys(this.changedAttributes())); 
     } 
    }, 
    triggerSilentChanges: function() { 
     if(!_.isEmpty(this.silentChanges)) { 
     var that = this; 
     _.each(this.silentChanges, function(key) { 
      that.trigger('change:' + key); 
      that.silentChanges = _.without(that.silentChanges, key); 
     }); 
     Backbone.Model.prototype.trigger.call(this, 'change'); 
     } 
    }, 
    _getOptions: function(key, val, options) { 
     if(key == null || _.isObject(key)) { 
     return val; 
     } 
     return options; 
    } 
    }); 
})(_, Backbone); 

Se voglio ottenere tutto è cambiato attributi Io uso proprietà silentChages all'interno del modello. Se voglio attivare l'evento per tutti gli attributi set/unset quando salvi aggiungo l'opzione 'triggerSilents: true'. Posso anche attivare manualmente tutti gli eventi di modifiche chiamando il metodo triggerSilentChanges.

0

Solo per riferimento, ho creato un piccolo frammento di codice che sostituisce il metodo Backbone.sync predefinito.

Il Backbone.sync sostituito indica quali attributi sono stati modificati dall'ultimo salvataggio() e funziona con entrambi i modelli e le raccolte.

https://github.com/ChiefORZ/backbone.dirty-sync

Problemi correlati