Вопрос по javascript – Магистральное табличное представление, потребляющее представление строки - как структурировать?
У меня есть коллекция моделей, которые я хочу отобразить в виде таблицы. Каждая модель должна быть представлена одной строкой в таблице, и эта строка должна быть сгенерирована с использованием шаблона. Я должен иметь возможность прикрепить обработчики событий к этой строке (скажем, щелкнуть), чтобы при оповещении о событии появлялась некоторая конкретная информация о модели, связанной с этой строкой.
Обычный способ, которым я видел подобные вещи, состоит в том, чтобы разбить каждую строку на собственное представление и иметь родительское представление (скажем, таблицу в этом случае), используя представление строки, чтобы сгенерировать html для включения в него. ваш код. Однако я не могу понять, как это работает с шаблонами.
В этом случае я не могу прикрепить события конкретно к RowView, так как он не имеет ссылки на элемент dom (this.el
для магистрали), он просто возвращает строку. Как мне достичь того, чего я хочу, используя шаблон с максимальной емкостью?
Вопрос заключается не только в событиях, шаблонах или использовании вложенных представлений, но скорее в правильном способе использования Backbone для достижения такого рода результатов.
Пример кода (также виграть на скрипке):
<code>/** View representing a table */ var TableView = Backbone.View.extend({ tagName: 'table', render: function() { var rows = _.map(this.collection.models, function(p) { return new RowView({model: p}).render(); }); $('body').html(this.$el.html(rows.join(''))); } }); /** View representing a row of that table */ var RowView = Backbone.View.extend({ render: function() { // imagine this is going through a template, but for now // lets just return straight html. return '<tr>' + '<td>' + this.model.get('name') + '</td>' + '<td>' + this.model.get('age') + '</td>' + '</tr>'; } }); var data = [ {'name': 'Oli', 'age': 25}, {'name': 'Sarah', 'age': 20}]; /** Collection of models to draw */ var peopleCollection = new Backbone.Collection(data); var tableView = new TableView({collection: peopleCollection}); tableView.render(); </code>
Спасибо!
Один из способов обработки иерархии представлений состоит в том, чтобы каждое представление отображало своих потомков и добавляло их к своимel
, События затем обрабатываются каждым представлением в соответствии с его моделью / коллекцией.
Внедрить ваш HTML как видel
и, таким образом, контролировать элемент контейнера, вы можете использоватьSetElement метод
setElement
view.setElement(element)
If you'd like to apply a Backbone view to a different DOM element, use setElement, which will also create the cached $el reference and move the view's delegated events from the old element to the new one.
Ваш пример может быть переписан как
var rowTemplate=_.template("<tr>"+
"<td class='name'><%= name %></td>"+
"<td class='age'><%= age %></td>"+
"</tr>");
/** View representing a table */
var TableView = Backbone.View.extend({
tagName: 'table',
initialize : function() {
_.bindAll(this,'render','renderOne');
},
render: function() {
this.collection.each(this.renderOne);
return this;
},
renderOne : function(model) {
var row=new RowView({model:model});
this.$el.append(row.render().$el);
return this;
}
});
/** View representing a row of that table */
var RowView = Backbone.View.extend({
events: {
"click .age": function() {console.log(this.model.get("name"));}
},
render: function() {
var html=rowTemplate(this.model.toJSON());
this.setElement( $(html) );
return this;
}
});
var data = [
{'name': 'Oli', 'age': 25},
{'name': 'Sarah', 'age': 20}];
/** Collection of models to draw */
var peopleCollection = new Backbone.Collection(data);
var tableView = new TableView({collection: peopleCollection});
$("body").append( tableView.render().$el );
И скрипкаhttp://jsfiddle.net/9avm6/5/