2012-02-24 13 views
8

Creo que lo que quiero hacer es bastante simple, simplemente no sé cómo hacerlo. Me gustaría activar mi propio evento cuando uno de mis modelos atribuye cambios con el fin de pasar algunos datos al controlador de eventos (si el cambio fue un aumento o una disminución en el valor).Sobrescritura de un evento de cambio de modelo principal

Básicamente quiero mi manejador de hacer esto en la vista

handler: function(increased) { 
    if(increased) { 
     alert("the value increased") 
    } 
    else { 
     alert("the value decreased") 
    } 
} 

// ... 

this.model.on("change:attr", this.handler, this); 
+1

¿Qué no funciona? – tkone

+0

hmmm tal vez mi pregunta no está clara, quiero saber cómo puedo pasar datos al manejador 'change: attr', ahora mismo ese evento está siendo activado" automágicamente "por backbone, cada vez que llamo a' set() 'en mi modelo. – Matthew

+0

¿Qué datos quiere pasar? Ya tendrá acceso al modelo y sabrá qué atributo se ha cambiado. – tkone

Respuesta

12

Aquí tienes: básicamente escuchas por change:myvar. Cuando ocurre un cambio, usa el modelo previous() para obtener el valor anterior. Dependiendo de si aumentó o disminuyó, se activa el evento apropiado. Puede escuchar estos eventos como se muestra en el initialize().

(function($){ 

    window.MyModel = Backbone.Model.extend({ 

     initialize: function() { 
      this.on('change:myvar', this.onMyVarChange); 
      this.on('increased:myvar', function() {     
       console.log('Increased');     
      }); 
      this.on('decreased:myvar', function() {     
       console.log('Decreased');     
      }); 
     }, 

     onMyVarChange: function() { 
      if (this.get('myvar') > this.previous('myvar')) { 
       this.trigger('increased:myvar'); 
      } else { 
       this.trigger('decreased:myvar'); 
      } 
     }    
    }); 

    window.mymodel = new MyModel({myvar: 1}); 
    mymodel.set({myvar: 2}); 
    mymodel.set({myvar: 3}); 
    mymodel.set({myvar: 1}); 

})(jQuery);​ 

Al ejecutar lo anterior, se imprimirán "Aumentado", "Aumentado", "Disminuido" en la consola.

+0

Esto parece una solución muy buena. Lo probaremos y volveremos a ti ... – Matthew

+0

funciona muy bien, aceptado – Matthew

+0

Funciona bastante bien, gracias por la información. Para mi caso, necesitaba detectar el evento en la vista que tiene un modelo adjunto. Entonces, el evento 'change: attribute_name' se activó incluso cuando el modelo se adjunta a la vista, además de cuando el valor del modelo cambia de la entrada DOM. Así que tuve que comprobar si 'this.model.get ('attribute_name')' es 'null' para evitar detectar el evento desencadenado en el método' initialize' de la vista. – codarrior

0

¿Qué pasa si usted enciende su propio evento personalizado después de escuchar el evento de cambio?

handler: function(increased) { 
    this.model.trigger('my-custom-event', stuff, you, want); 
}, 
myHandler: function(stuff, you, want){ 
    // Do it... 
} 
// ... 
this.model.on("change:attr", this.handler, this); 
this.model.on('my-custom-event, this.myHandler, this); 
2

Basta con mirar a previousAttributes()

continuación, puede comparar:

If(this.get(attr) > this.previousAttributes()[attr]){ 
    console.log('bigger'); 
} else { 
    console.log('smaller'); 
} 

Si utiliza eso en su controlador de eventos change ya está todo listo. No hay necesidad de un disparador personalizado o una tonelada de código.

EDITAR

Esto es de mi proyecto Backbone.Validators y cómo puedo obtener la lista de todos los atributos que han cambiado durante la etapa de validación:

var get_changed_attributes = function(previous, current){ 
    var changedAttributes = []; 
    _(current).each(function(val, key){ 
     if(!_(previous).has(key)){ 
      changedAttributes.push(key); 
     } else if (!_.isEqual(val, previous[key])){ 
      changedAttributes.push(key); 
     } 
    }); 
    return changedAttributes; 
}; 

Esto requiere subrayado 1.3.1 porque está utilizando _.has. Sin embargo, si no puedes actualizar eso es algo fácil de reemplazar. En su caso, usted pasaría this.previousAttributes() y this.attributes

+0

esto se parece a lo que se le ocurrió a @ggozad. Acepté el suyo porque me gustaba la idea de escuchar 'this.on ('changed: attr'' y activar un evento personalizado en el controlador. Gracias por su ayuda :) – Matthew

+0

@matthew Yup. Esa es la mejor manera de hacerlo.La idea de esto es que puedes hacerlo genéricamente comparando atributos, lo que hace que sea más fácil de reutilizar si lo necesitas. ¡Gracias por la respuesta! – tkone

Cuestiones relacionadas