2012-02-09 8 views
16

Tengo un Backbone-Model. Con model.set() Puedo establecer un valor local, con model.save() Puedo guardar todo el modelo en el servidor.backbone.js: ¿Hay algún cambio desde la última vez que se guardó el servidor?

Cómo sé si hubo un cambio desde la última vez que se guardó el servidor, lo que significa que la versión local está sucia.

model.isNew(); funciona solo si el modelo nunca se ha guardado en el servidor.

+0

el bit de modificación no es lo mismo que comprobar si ha cambiado (dependiendo de su definición). Ejemplo: el modelo podría ser inicialmente bueno: verdadero, cambia a es Bueno: falso, luego vuelve a ser Bueno: verdadero. El bit más sucio estaría activado en este caso, pero el modelo en realidad no está cambiado. ¿Está bien? – Matt

Respuesta

16

EDIT: Esta respuesta fue escrito antes de la versión 1.0 de Backbone. A partir de la versión Backbone actual (1.2.2) hasChanged ya no se reflejan los cambios "desde el último guardado". En cambio, refleja los cambios "desde la última establecida en".


Escuche los eventos de cambio o marque hasChanged.

Si el modelo ha cambiado, puede ahorrar en el cambio. Incluso puede cablear su método de guardar para disparar cuando ocurre el evento de cambio.

Si no desea guardar el cambio, configure una propiedad para que el modelo esté sucio y desactívela cuando lo guarde explícitamente.

Algo así como:

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

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

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

¿Pero hay una versión sin un poco sucio? – knub

+0

@knub ¿Qué quieres decir? Backbone no proporciona esto. Proporcionan el evento 'change' y el método' hasChanged'. Esta es una forma de implementar un sistema de almacenamiento de datos lazy-save-only-if-dirty-data. Lo ideal es que simplemente llame a 'model.save()' cuando reciba el evento 'change'. De esta manera, si pierde el cliente, no pierde sus cambios. – tkone

+0

Pensé que había alguna funcionalidad oculta en Backbone-Core que podría proporcionarme esa información. Quiero decir, Backbone TIENE esa información, simplemente no me la ofrece. Y el bit sucio está sucio, ya sabes;). Pero está bien, obviamente no hay otra solución (¿todavía?). – knub

4

opción alternativa es fijar todas las actualizaciones a las actualizaciones 'silenciosas', y luego recoger los cambios cuando se desea sincronizar:

// 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

no parece estar funcionando con la red troncal 1.1.2 – user116293

5

estoy trabajando con CouchDB y Couch tiene un atributo _rev que cambia después de cada éxito de guardado. He resuelto el problema de la "ya-pasado-server-save" colocando el código siguiente en los modelos inicializar función:

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

Todas las respuestas que sugieren la escucha de cambios (usando eventos) son correctas a menos que pase {silenciosa: verdadera} opción. En ese caso, debe sobrescribir el método de configuración predeterminado para guardar los atributos que han cambiado y restablecer esa lista después de llamar al método de guardar.

La respuesta de MidnightLightning no es correcta. Si establecimiento de llamada método de dos veces y luego changedAttributes volverán sólo los atributos que tiene el cambio desde la última llamada conjunto - está en la documentación Backbone:

changedAttributesmodel.changedAttributes([attributes])

Recuperar un hash de atributos sólo el del modelo que han cambiado desde la último conjunto, o falso si no hay ninguno.

En mi caso he resuelto el problema con este código:

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

Si quiero conseguir todo cambió atributos utilizo propiedad silentChages dentro del modelo. Si deseo desencadenar evento para todos los atributos set/unset cuando guardo, agrego la opción 'triggerSilents: true'. También puedo activar manualmente todos los eventos de cambios llamando al método triggerSilentChanges.

0

Solo para referencia, hice un pequeño fragmento de código que reemplaza el método predeterminado Backbone.sync.

El Backbone.sync reemplazado determina qué Atributos ha cambiado desde el último save() y funciona tanto con modelos como con colecciones.

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

Cuestiones relacionadas