Aquí hay un par de posibilidades
1. centralizados: tienda ClosedTune
objetos en el TuneBook
ejemplo
tienda una referencia a cada ClosedTune
en tune_book.tunes
. Cómo llenas tune_book.tunes
depende de ti; ya que mencionó un método sumador en TuneBook
, eso es lo que he ilustrado a continuación.
En el controlador TuneBook
caso, recuperar el ClosedTune
de tune_book.tunes
mediante el uso de algo así como el atributo id
del destino del evento como clave. A continuación, llame al controlador Tune
o ClosedTune
.
http://jsfiddle.net/p5QMT/1/
var Tune = Backbone.View.extend({
className: "tune",
click_handler: function (event) {
event.preventDefault();
console.log(this.id + " clicked");
},
render: function() {
this.$el.html(
'<a href="" class="button">' + this.id + '</a>'
);
return this;
}
});
var ClosedTune = Tune.extend({});
var OpenTune = Tune.extend({
events: {
"click .button" : 'click_handler'
}
});
var TuneBook = Backbone.View.extend({
events: {
"click .tune .button" : 'click_handler'
},
click_handler: function (event) {
var tune = this.options.tunes[
$(event.target).closest(".tune").attr('id')
];
tune.click_handler(event);
},
add_tune: function (tune) {
this.options.tunes[tune.id] = tune;
this.$el.append(tune.render().el);
},
render: function() {
$("body").append(this.el);
return this;
}
});
var tune_book = new TuneBook({
tunes: {}
});
[1, 2, 3].forEach(function (number) {
tune_book.add_tune(new ClosedTune({
id: "closed-tune-" + number
}));
});
tune_book.render();
var open_tune = new OpenTune({
id: "open-tune-1"
});
$("body").append(open_tune.render().el);
2. descentralizada: asociar el objeto vista con el objeto DOM utilizando jQuery.data()
Cuando se crea un ClosedTune
, almacenar una referencia a él, por ejemplo, this.$el.data('view_object', this)
.
En el detector de eventos, obtenga ClosedTune
, p. Ej. $(event.target).data('view_object')
.
Se puede utilizar el mismo controlador exacto para ClosedTune
(en TuneBook
) y OpenTune
, si lo desea.
http://jsfiddle.net/jQZNF/1/
var Tune = Backbone.View.extend({
className: "tune",
initialize: function (options) {
this.$el.data('view_object', this);
},
click_handler: function (event) {
event.preventDefault();
var tune =
$(event.target).closest(".tune").data('view_object');
console.log(tune.id + " clicked");
},
render: function() {
this.$el.html(
'<a href="" class="button">' + this.id + '</a>'
);
return this;
}
});
var ClosedTune = Tune.extend({
initialize: function (options) {
this.constructor.__super__.initialize.call(this, options);
}
});
var OpenTune = Tune.extend({
events: {
"click .button" : 'click_handler'
}
});
var TuneBook = Backbone.View.extend({
events: {
"click .tune .button": Tune.prototype.click_handler
},
add_tune: function (tune) {
this.$el.append(tune.render().el);
},
render: function() {
$("body").append(this.el);
return this;
}
});
var tune_book = new TuneBook({
tunes: {}
});
[1, 2, 3].forEach(function (number) {
tune_book.add_tune(new ClosedTune({
id: "closed-tune-" + number
}));
});
tune_book.render();
var open_tune = new OpenTune({
id: "open-tune-1"
});
$("body").append(open_tune.render().el);
respuesta al comentario
consideré la opción 1, pero decidió no hacerlo como ya tengo una colección de modelos sintonizar la tunebook y no quería otro objeto I' Necesito mantenerme sincronizado
Supongo que depende de qué tipo de limpieza/sincronización sientes que debes hacer, y por qué.
(por ejemplo, en TuneModel.remove() Me gustaría que tenga que quitar la vista de la lista de tunebook de puntos de vista ... probablemente necesitaría eventos para hacer esto, por lo que un evento única solución comienza a parecer más atractivo).
¿Por qué se siente que "tiene que quitar la vista de la lista de tunebook de puntos de vista"? (No estoy sugiriendo que no debas, solo preguntando por qué quieres querer hacerlo). Como crees, ¿cómo crees que el enfoque de @ ggozad difiere al respecto?
Ambas técnicas almacenan objetos ClosedTune
en la instancia TuneBook
. En la técnica de @ ggozad, está escondida detrás de una abstracción que tal vez lo haga menos obvio.
En mi ejemplo, están almacenados en un objeto JS simple (tune_book.tunes
). En @ ggozad's están almacenados en la estructura _callbacks
utilizada por Backbone.Events
.
Adición de un ClosedTune
:
1.
this.options.tunes[tune.id] = tune;
2.
this.on('buttonClick:' + tune.id, tune.handler, tune);
Si desea deshacerse de un ClosedTune
(diga lo saque del documento con tune.remove()
y quieres que el objeto de vista se haya ido por completo), usar el enfoque de @ ggozad dejará una referencia huérfana al ClosedTune
i n tune_book._callbacks
a menos que realice el mismo tipo de limpieza que tendría sentido con el enfoque que sugerí:
1.
delete this.options.tunes[tune.id];
tune.remove();
2.
this.off("buttonClick:" + tune.id);
tune.remove();
La primera línea de cada ejemplo es opcional - dependiendo si desea limpiar los objetos ClosedTune
o no.
La opción 2 es más o menos lo que estoy haciendo en este momento, pero (por otras razones) también guardo el modelo como un atributo de datos en la vista. tiene que ser una mejor manera que almacenar referencias en todo el lugar.
Bueno, en última instancia, se reduce a su preferencia sobre cómo estructurar las cosas. Si prefiere almacenar los objetos de vista de una manera más centralizada, puede almacenarlos en la instancia TuneBook
en lugar de usar jQuery.data
. Ver # 1: Centralizado.
un modo u otro te están las referencias a los objetos ClosedTune
almacenamiento: el uso de jQuery.data
, o en un objeto plano en el TuneBook
, o en _callbacks
en el TuneBook
.
Si te gusta el enfoque de @ ggozad por razones que entiendes, ve por ello, pero no es mágico. Como se presenta aquí, no estoy seguro de qué ventaja se supone que proporciona el nivel extra de abstracción en comparación con la versión más directa que presento en el n. ° 1. Si hay alguna ventaja, no dude en escribirme.
Si los eventos van a ser ejecutados por los controladores en el modelo 'Tune' por qué quieres hacer el desvío' ChildView -> ParentView -> Model' ... puedes ejecutar 'Model.handler' directamente desde' ChildView' .. Por otro lado, puede usar el 'Modelo' como el messenger: puede modificar el estado del Modelo desde el ChildView y dejar que el ParentView escuche esta modificación. – fguillen
@fguillen Es mucho menos eficiente enlazar los eventos (quizás debería ser claro me refiero a eventos DOM en lugar de eventos personalizados Backbone) al nodo DOM de cada vista secundaria en lugar de solo una vez al nodo DOM de la vista principal. En la tabla de 300 filas generada por el rendimiento de mi aplicación es notablemente lento cuando se vincula directamente a cada fila. Lo que necesito es 'ParentView -> [childView] -> childModel' – wheresrhys