[Backbone]如何获取列表中单击条目的model
分类:Backbone 标签:Backbone
经常会遇到这种情况,使用collector渲染出列表后,怎么得到我所单击的item的model呢?从而获取数据...
如何获取列表中单击条目的model呢?这取决于你渲染list的方式,我总结出有两种方式可以渲染:
list和item用一个view来渲染
list和item分别用各自的view来渲染
下面举例来说明,场景为将collection中的假数据渲染到id为showIt的div中。
一个View来组织
<script id="item-template" type="text/x-jquery-tmpl">
<li><a href="#">${name}</a></li>
</script>
// Model
Item = Backbone.Model.extend({});
ItemCollection = Backbone.Collection.extend({
model: Item
});
// View
ItemListView = Backbone.View.extend({
tagName: "ul",
events: {
"click a": "clicked"
},
clicked: function(e){
e.preventDefault();
// ??? 我们怎样获取呢?
var item = ??? // TODO 01
var name = item.get("name");
alert(name);
},
render: function(){
var template = $("#item-template");
var el = $(this.el);
// 这里需要从collection中取出model数据进行渲染,
// 两种方式在这里的写法会有所不同
// TODO 02
$("#showIt").html(view.el);
}
});
var items = new ItemCollection([
{id: 1, name: "item 1"},
{id: 2, name: "item 2"},
{id: 3, name: "item 3"}
]);
var view = new ItemListView({collection: items});
view.render();
先来看TODO 02处,我们只需遍历collection取得model将数据都append到当前的el,即ul元素中,然后html到#showIt,代码如下:
this.collection.each(function(model){
var html = template.tmpl(model.toJSON());
el.append(html);
});
再来看TODO 01处,由于我们直接将model渲染到了list的view中,并没有建立model和所单击item之间的关系,所以需要通过其他途径来保存model,我们给item的元素(li)添加data属性来保存。如下:
<script id="item-template" type="text/x-jquery-tmpl">
<li><a href="#" data-id="${id}">${name}</a></li>
</script>
然后TODO 01 处的代码就可以这么写:
var id = $(e.currentTarget).data("id");
var item = this.collection.get(id);
这种做法比较适用于item对model的操作比较少,最好只是用来展示model的数据。
两个View
这种做法是ListView中的每个item都是一个View,它存放着model,代码如下:
Item = Backbone.Model.extend({});
ItemCollection = Backbone.Collection.extend({
model: Item
});
ItemListView = Backbone.View.extend({
tagName: "ul",
initialize: function(){
_.bindAll(this, "renderItem");
},
renderItem: function(model){
var itemView = new ItemView({model: model});
itemView.render();
$(this.el).append(itemView.el);
},
render: function(){
this.collection.each(this.renderItem);
}
});
ItemView = Backbone.View.extend({
tagName: "li",
events: {
"click a": "clicked"
},
clicked: function(e){
e.preventDefault();
var name = this.model.get("name");
alert(name);
},
render: function(){
var template = $("#item-template");
var html = template.tmpl(this.model.toJSON());
$(this.el).append(html);
}
});
var items = new ItemCollection([
{id: 1, name: "item 1"},
{id: 2, name: "item 2"},
{id: 3, name: "item 3"}
]);
var view = new ItemListView({collection: items});
view.render();
$("#showIt").html(view.el);
在ListView中的renderItem方法中,迭代collection时都要为每一个item去new一个ItemView,所以当单机item时就可以通过this.model得到该model,这种方式比较适合对item的操作比较多的情况,可以很方便取到当前单击的model。