backbone.js - for - backbone view events
Cómo saber si el elemento ya está en el DOM al crear una nueva vista Backbone (2)
Conectando un Backbone. Ver a un elemento DOM existente es simple:
//get a referent to the view element
var $el = $("#foo");
//initialize new view
var view = new FooView({el:$el});
La vista ahora maneja los #foo
elemento #foo
y todos los demás bondades de visualización. No deberías llamar a view.render
. Si lo hace, volverá a mostrar la vista al elemento. Esto significa que no puede definir ningún código necesario en el método de render
.
En cuanto a cómo saber qué elementos ya están en el DOM, y cómo encontrar el elemento correspondiente para cada vista, es un poco más complicado de responder sin saber exactamente cómo son sus datos y html. Como consejo general, considere usar atributos data-*
para hacer coincidir los elementos.
Digamos que tienes un árbol DOM:
<ul id="list">
<li data-id="1">...</li>
<li data-id="2">...</li>
<li data-id="5">...</li>
</ul>
Podría vincular / renderizar un modelo al contenedor de la siguiente manera:
var view;
//container element
var $list = $("ul#list");
//find item node by "data-id" attribute
var $item = $list.find("li[data-id=''" + model.id+ "'']");
if($item.length) {
//element was in the DOM, so bind to it
view = new View( {el:$item, model:model} );
} else {
//not in DOM, so create it
view = new View( {model:model} ).render();
$list.append(view.el);
}
esta es la situación: cuando la página se abre por primera vez, ya ha preparado DOM por servidor (php).
Si el usuario tiene Javascript activado, entonces quiero convertir mi página a la aplicación web (o como se llame). Tan pronto como se inicializa Javascript, Backbone recupera la colección del servidor. El problema es que algunos de estos elementos recuperados ya están en la página.
¿Ahora cómo puedo marcar esos artículos que ya están en el DOM? ¿Y cómo puedo atarlos con la vista Backbone?
Ok, logré hacer eso así:
var Collection = Backbone.Collection.extend({...});
var ItemView = Backbone.View.extend({...});
var ItemsView = Backbone.View.extend({
initialize: function () {
var that = this,
coll = new Collection;
coll.fetch({ success: function () {
that.collection = coll;
that.render();
}});
},
render: function () {
this.collection.each(this.addOne, this);
},
addOne: function (model) {
var selector = ''#i''+model.get("id");
if( $(selector).length ) {
//If we are here, then element is already in the DOM
var itemView = new ItemView({ ''model'': model, ''el'': selector, ''existsInDom'': true });
} else {
var itemView = new ItemView({ ''model'':model });
}
}
});