2012-04-03 19 views
10

Estoy ejecutando Backbone js 0.9.2 en Rails 3.2.2, tengo una página para agregar filas de costos. Un costo tiene 3 TextFields: título, descripción y precio.Cola Ajax Backbone js

Ahorro cada coste en desenfoque.

model.save() recibe llamadas varias veces con intervalos muy cortos. Que emite un pedido create(post) entonces un pedido update(put) poco después. El problema que estoy experimentando es que la solicitud PUT a veces llega al servidor antes del POST, y el resultado es que el modelo se crea y persiste dos veces (duplicados).

Para ahorrar en desenfoque es el comportamiento solicitado, por lo que necesito una forma de poner en cola las solicitudes. He leído algo sobre Spine js, y que lo resuelven mediante algún tipo de cola. También miré en this, pero parece que no puedo resolver esto.

Parece que esto debería ser un problema común, trabajando con "aplicaciones de una sola página", pero no puede encontrar nada al respecto.

Respuesta

9

Puede anular el método guardar y crear una cola con deferred object. Por ejemplo,

var MDef = Backbone.Model.extend({ 
    url: "/echo/json/?delay=3", 

    initialize: function() { 
     this.queue = $.Deferred(); 
     this.queue.resolve(); 
    }, 

    save: function(attrs,options) { 
     var m = this; 
     console.log("set "+JSON.stringify(attrs)); 

     // this.queue = this.queue.pipe with jquery<1.8 
     this.queue = this.queue.then(function() { 
      console.log("request "+JSON.stringify(attrs)); 
      return Backbone.Model.prototype.save.call(m, attrs, options); 
     });    
    } 
}); 

var m = new MDef(); 
m.save({title: "a title"}); 
m.save({description: "a description"}); 
m.save({price: "a price"}); 

Y un violín: http://jsfiddle.net/nikoshr/8nEUm/

+0

Usando esto con excelentes resultados, ¡gracias! –

3

Usuario debounce de underscore.js.

Crea y devuelve una nueva versión eliminada de la función pasada que pospondrá su ejecución hasta que hayan transcurrido los milisegundos de espera desde la última vez que se invocó.

De esta forma solo se disparará una vez después del último evento blur.

+2

Eso no es una solución a prueba de balas, se puede resolver la mayoría de los casos, pero todavía hay una posibilidad de que los datos se pueden perder. –

+0

@TimBrunsmo, @abraham 'rebote' es correcto. ¿Cómo se perderán los datos? * Puedes * reemplazarlo con '_.throttle' si deseas forzar guardados periódicos. – ggozad

+1

@ggozad Si un campo está enfocado y el usuario decide abandonar la página, por ejemplo, al hacer clic en el botón "siguiente", existe la posibilidad de que el evento de desenfoque nunca emita una solicitud. Si hay una cola, puede verificar si la cola ha finalizado y luego dejar que el usuario pase. –