给定一个页面使用Backbone.js将一个集合绑定到一个视图(RowsView
,创建一个<ul>
),创建子视图(RowView
,创建<li>
})对于集合中的每个模型,我有一个问题是为集合中的那些模型设置内联编辑。
我在edit()
视图上创建了RowView
方法,用文本框替换li
内容,如果用户在该文本框中按tab
,我想触发列表中下一个View的edit()
方法。
我可以在集合中获得下一个模型的模型:
// within a RowView 'keydown' event handler
var myIndex = this.model.collection.indexOf(this.model);
var nextModel = this.model.collection.at(myIndex+1);
但问题是,如何找到附加到该模型的视图。父RowsView
视图不会保留对所有子视图的引用;它的render()
方法只是:
this.$el.html(''); // Clear
this.model.each(function (model) {
this.$el.append(new RowView({ model:model} ).render().el);
}, this);
我是否需要重写它以保留一个单独的指针数组,指向它下面的所有RowView
?或者是否有一种聪明的方法可以找到附有已知模型的View?
这是整个问题的一个问题:http://jsfiddle.net/midnightlightning/G4NeJ/
答案 0 :(得分:11)
在模型中存储对View的引用并不优雅,但是您可以将View与模型链接到事件,请执行以下操作:
// within a RowView 'keydown' event handler
var myIndex = this.model.collection.indexOf(this.model);
var nextModel = this.model.collection.at(myIndex+1);
nextModel.trigger('prepareEdit');
在RowView中监听事件prepareEdit并在该侦听器中调用edit(),如下所示:
this.model.on('prepareEdit', this.edit);
答案 1 :(得分:2)
我要说你的RowsView
应该跟踪其组件RowView
。个人RowView
确实是RowsView
的一部分,因此视图应该跟踪其各个部分。
因此,您的RowsView
会有render
方法,如下所示:
render: function() {
this.child_views = this.collection.map(function(m) {
var v = new RowView({ model: m });
this.$el.append(v.render().el);
return v;
}, this);
return this;
}
然后你只需要一种方法将 Tab 转换为this.child_views
中的索引。
一种方法是使用事件,Backbone视图混合了Backbone.Events
,因此视图可以触发自己的事件,其他事情可以监听这些事件。在RowView
中你可以拥有:
events: {
'keydown input': 'tab_next'
},
tab_next: function(e) {
if(e.keyCode != 9)
return true;
this.trigger('tab-next', this);
return false;
}
并且RowsView
v.on('tab-next', this.edit_next);
this.collection.map
edit_next
,您可以edit_next: function(v) {
var i = this.collection.indexOf(v.model) + 1;
if(i >= this.collection.length)
i = 0;
this.child_views[i].enter_edit_mode(); // This method enables the <input>
}
这样排序:
RowsView
演示:http://jsfiddle.net/ambiguous/WeCRW/
这方面的一个变体是将RowView
的引用添加到tab_next
,然后this.parent_view.edit_next()
可以直接调用keydown
。
另一个选择是将RowsView
处理程序放在RowView
中。这在RowsView
和var RowsView = Backbone.View.extend({
//...
events: {
'keydown input': 'tab_next'
},
render: function() {
this.child_views = this.collection.map(function(m, i) {
var v = new RowView({ model: m });
this.$el.append(v.render().el);
v.$el.data('model-index', i); // You could look at the siblings instead...
return v;
}, this);
return this;
},
tab_next: function(e) {
if(e.keyCode != 9)
return true;
var i = $(e.target).closest('li').data('model-index') + 1;
if(i >= this.collection.length)
i = 0;
this.child_views[i].enter_edit_mode();
return false;
}
});
之间增加了一点耦合,但在这种情况下这可能不是一个大问题,但它比事件解决方案有点丑陋:
{{1}}