如果你知道模型,找一个Backbone.js查看?

时间:2012-07-13 15:48:41

标签: backbone.js

给定一个页面使用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/

2 个答案:

答案 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中。这在RowsViewvar 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}}

演示:http://jsfiddle.net/ambiguous/ZnxZv/

相关问题