2012-07-13 84 views
8

給定一個頁面,使用Backbone.js將一個集合綁定到一個視圖(RowsView,創建一個<ul>),該集合爲集合中的每個模型創建子視圖(RowView,創建<li>),但我遇到了一個問題爲集合中的這些模型進行內聯編輯。如果您知道該模型,請查找Backbone.js視圖?

我創建的RowView認爲,與文本框取代了li內容的edit()方法,如果用戶在文本框中按下tab同時,我想以觸發下一個視圖的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 s具有下呢?或者有沒有一種巧妙的方式來查找附有已知模型的視圖?

這裏是整個問題的的jsfiddle:http://jsfiddle.net/midnightlightning/G4NeJ/

回答

11

這是不優雅存儲在模型中的視圖的引用,但是你可以鏈接與事件模型的視圖,這樣做:

// 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並在監聽通話編輯(),像這樣:

this.model.on('prepareEdit', this.edit); 
2

我會說,你RowsView應該跟蹤其組件RowView s。個人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; 
} 

然後你只需要一種方法來一個標籤轉換爲指數this.child_views


一種方法是使用事件,骨幹觀點都有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將在this.collection.mapv.on('tab-next', this.edit_next);,你可以有一個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,然後tab_next可以直接添加請致電this.parent_view.edit_next()


另一種選擇是把​​處理程序中RowsView。這增加了一個位RowViewRowsView之間的耦合,但是這可能不是在這種情況下,一個很大的問題,但它是比事件的解決方案醜陋一點:

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/