backbone.js

backbone.js - ¿Hay alguna manera de vincular el activador.change() de un Modelo a la función.render() de una Vista sin crear más de uno?



(5)

A partir de Backbone 0.9.2 (y posiblemente antes), la función on() o bind() (así como su contraparte off() o unbind() ) toma un parámetro de context opcional para usarlo cuando se le llama.

Asi que,

SomeView = Backbone.View.extend({ initialize: function(){ _.bindAll(this, "render"); this.model.bind(''change'', this.render); }, render: function(){ this.$el.html(this.template(this.model.toJSON())); return this; } });

puede llegar a ser

SomeView = Backbone.View.extend({ initialize: function(){ this.model.bind(''change'', this.render, this); }, render: function(){ this.$el.html(this.template(this.model.toJSON())); return this; } });

Consulte la documentación de on() .

Una vista normalmente espera un objeto con estos atributos antes de que pueda representarse:

{ el: ''#someelement'', model: someModel }

Una Vista también nos permite vincular los eventos del modelo a funciones en la vista:

initialize: function() { this.model.bind(''change'', this.renderFromModel, this); }, render: function() { $(this.el).html(this.template(this.model.toJSON())); return this; }, renderFromModel: function() { var t = _.template($(''#some-template'').html()); $(''item-'' + this.cid).html(t(this.toJSON())); return this; },

El problema es que la primera vez que instanciamos una Vista para renderizar, está esperando un objeto con un Modelo; y la segunda vez que renderizamos la vista cuando es llamada desde dentro del Modelo, no lo es. Debido a esto, termino creando dos funciones render ().

¿Hay una mejor manera de lograr un único elemento de representación que también pueda responder a los eventos de model.change ()?


Creo que debes asegurarte de que tu método de renderización siempre esté vinculado a la vista llamando al método bindAll de underscore.js.

SomeView = Backbone.View.extend({ initialize: function(){ _.bindAll(this, "render"); this.model.bind(''change'', this.render); }, render: function(){ $(this.el).html(this.template(this.model.toJSON())); return this; } });


Una mejor solución es usar la función listenTo :

SomeView = Backbone.View.extend({ initialize: function(){ this.listenTo(this.model, ''change'', this.render); }, render: function(){ this.$el.html(this.template(this.model.toJSON())); return this; } });

De esta forma, el objeto de vista es consciente de los enlaces que realizó, y todos ellos se pueden eliminar con la función stopListening y no necesita llamar bind o bindAll explícitamente. Por último, pero no menos importante, el código es más limpio en mi opinión.


Use el método _.bind () para establecer el alcance

this.model.bind(''change'', _.bind(this.render, this));


crear instancia de modelo en la vista

var myapp.myView = new View({ model: new Model });

y cuando inicialice Backbone.View inside add this ... qué render se llamará cada vez que haya cambios en los atributos del modelo de sus valores predeterminados

this.model.bind(''change'', this.render,this)