我会说你RowsView
应该跟踪它的 component RowView
s。个体RowView
s 确实是 the 的一部分,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;
}
然后,您只需要一种将 a 转换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>
}
演示:http: //jsfiddle.net/ambiguous/WeCRW/
对此的一个变体是添加RowsView
对RowView
s 的引用,然后tab_next
可以直接调用this.parent_view.edit_next()
.
另一种选择是将keydown
处理程序放在RowsView
. 这在 and 之间增加了一些耦合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;
}
});
演示:http: //jsfiddle.net/ambiguous/ZnxZv/