collections - template - Renderiza una colección Backbone.js
underscore js que es (2)
Soy un Backbone.js n00b y estoy tratando de entenderlo. Sé cómo renderizar un modelo usando una vista y el motor de plantillas underscore.js incorporado. Ahora intento renderizar una colección y ahí es donde me quedo atascado. No hay ningún servidor aquí, así que no estoy buscando nada de forma remota, solo una página HTML simple con algo de JavaScript.
ContinentModel = Backbone.Model.extend({});
ContinentsCollection = Backbone.Collection.extend({
model: ContinentModel,
initialize: function () {
this.continentsView = new ContinentsView;
this.bind("reset", this.continentsView.render);
}
});
ContinentsView = Backbone.View.extend({
el: ''#continents'',
template: _.template($(''#continents-template'').html()),
render: function() {
var renderedContent = this.template(this.collection.toJSON());
$(this.el).html(renderedContent);
return this;
}
});
$(function() {
var continentsCollection = new ContinentsCollection();
continentsCollection.reset([{name: "Asia"}, {name: "Africa"}]);
});
Se rompe en la línea de atributo de la plantilla en la vista, pero no estoy seguro de que sea allí donde tengo que mirar. ¿Se supone que tengo que renderizar una colección o perder el punto por completo aquí (tal vez las colecciones son solo objetos de agrupación y no debería verlo como una lista que puedo mostrar)?
Gracias por ayudar...
También vale la pena señalar que existen complejidades adicionales que aceleran rápidamente al renderizar una colección en una vista. Por ejemplo, la vista generalmente debe volver a procesarse cuando los modelos se agregan o eliminan de la colección. No es una ciencia revolucionaria implementar su propia solución, pero probablemente valga la pena analizar las soluciones existentes, ya que existen bastantes probadas.
Backbone.CollectionView es una clase de vista de colección robusta que maneja la selección de modelos en respuesta a los clics del mouse, el reordenamiento de la colección en función de la función de arrastrar y soltar, el filtrado de modelos visibles, etc.
Varios frameworks populares construidos sobre la red troncal también proporcionan clases simples de vista de colección, como Backbone.Marionette , Chaplin y Layout Manager .
A pesar de que Backbone en sí mismo no proporciona ninguna estructura para procesar una colección, no es un problema trivial y muchas personas tienen opiniones diferentes sobre cómo se debe hacer . Afortunadamente, es una necesidad tan común que ya hay bastantes buenas opciones en el ecosistema.
El problema es que cuando defines ContinentsView, la plantilla se evalúa y usa $(''#continents-template'')
, pero el DOM aún no está listo, por lo que no encuentra la plantilla.
Para resolverlo, simplemente mueva la asignación de plantilla en la función de inicialización:
ContinentsView = Backbone.View.extend({
el: ''#continents'',
initialize: function() {
this.template = _.template($(''#continents-template'').html());
}
...
En cuanto a las colecciones, sí, son objetos de agrupación, específicamente conjuntos de modelos.
Debe crear el código para que los modelos (y colecciones) NO conozcan las vistas, solo las vistas conocen los modelos.
ContinentModel = Backbone.Model.extend({});
ContinentsCollection = Backbone.Collection.extend({
model: ContinentModel,
// no reference to any view here
});
ContinentsView = Backbone.View.extend({
el: ''#continents'',
initialize: function() {
this.template = _.template($(''#continents-template'').html());
// in the view, listen for events on the model / collection
this.collection.bind("reset", this.render, this);
},
render: function() {
var renderedContent = this.template(this.collection.toJSON());
$(this.el).html(renderedContent);
return this;
}
});
$(function() {
var continentsCollection = new ContinentsCollection();
continentsCollection.reset([{name: "Asia"}, {name: "Africa"}]);
// initialize the view and pass the collection
var continentsView = new ContinentsView({collection: continentsCollection});
});