-1

我試圖將排序的Backbone.Collection與另一個列表同步,例如,一個JavaScript數組。我使用下面的代碼(jsfiddle):與排序的Backbone.Collection同步陣列

var coll = new Backbone.Collection(); 
coll.comparator = "label"; 

var list = [] 

coll.on("add", function (model, collection, options) { 
    list.splice(collection.indexOf(model), 0, model.get("label")); 
}); 

coll.add([ 
    {label: "1"}, 
    {label: "3"}, 
    {label: "5"}, 
    {label: "4"}, 
    {label: "2"} 
]); 

在這個例子中,這個結果在下面的列表:1, 2, 3, 5, 4。根本原因是,在添加事件處理程序中,Backbone.Collection已經被所有模型填充,而JS數組卻沒有。由於添加事件是以插入順序觸發的,而不是按排序順序觸發的,所以這會導致數組中的順序錯誤。

我將如何更改我的同步方法/添加處理程序以使其工作?

回答

0

首先,你需要聽sort事件

this.listenTo(this.collection, 'sort', this.sortList); 

然後data-id標識符添加到每個列表項

var li = $("<li>", { "data-id": model.get("label") }).html(model.get("label")); 

然後根據不等於位置排序html項目

sortList: function(collection, options) { 
     collection.forEach(function(model, index) { 
      var li1 = this.$el.children().eq(index), 
       li2; 
      if (model.get("label") != li1.data("id")) { 
       li2 = this.$el.children("[data-id=" + model.get("label") + "]"); 
       li1.before(li2); 
      } 
     }, this); 
    }, 

的jsfiddle鏈接http://jsfiddle.net/n0fdmb8a/3/

+0

感謝您的回覆,但正如我在另一個[答案的評論]中指出的(http://stackoverflow.com/questions/25992107/synching-an-array-with-a-sorted-backbone-collection/26004958?iemail= 1&noredirect = 1#comment40706037_25992898),我不想在每次更改時重新創建列表。 – 2014-09-24 07:07:13

+0

我更新了我的回答 – 2014-09-24 09:04:12

+0

感謝您的建議。基於這種方法,我進一步簡化了代碼。由於這似乎是唯一可行的方法,我接受了這個答案。 JS小提琴爲ul/li(http://jsfiddle.net/schm/n0fdmb8a/4/) – 2014-09-24 09:32:51

0

這聽起來像初始化過程中出現你的錯誤:

var coll = new Backbone.Collection([ 
    {label: "1"}, 
    {label: "3"}, 
    {label: "5"}, 
    {label: "4"}, 
    {label: "2"} 
], { comparator: 'label') 

var list = coll.pluck('label') 

// Assuming your add-handler works, you can keep that around for future add's 
coll.on("add", function (model, collection, options) { 
    list.splice(collection.indexOf(model), 0, model.get("label")); 
}); 

如果這些還不夠,那麼你就需要做一些工作涉及sync事件,其中add的後發生。不過,我會建議你的li的視圖只是聽coll然後完全重新呈現時,每當coll火災關閉add,removesort。這將完全阻止試圖保持兩個陣列彼此同步,這在編程中是不可能的。一般情況下,你需要創建一個數據結構來處理互動,但您的收藏應該是足夠了:

var LabelsView = Backbone.Collection.extend({ 
    el: '#my-list', 
    template: '<% coll.each(function(model){ %> <li><%- model.get("label") %></li><% }); %>', 
    initialize: function(){ 
     this.listenTo(this.collection, 'add remove sort', this.render) 
    } 
    render: function(){ 
     this.$el.html(this.template({ coll: this.collection })) 
    } 
}) 

var labelView = new LabelsView({ collection: coll }) 
+0

並初始化過程中不僅會出現錯誤。每當我在集合的一次添加調用中添加一組未加分類的模型時,就會發生這種情況。因此你的第一個提議是不夠的。正如我在另一個[答案的評論]中指出的(http://stackoverflow.com/questions/25992107/synching-an-array-with-a-sorted-backbone-collection/26004958?iemail=1&noredirect=1#comment40706037_25992898),重新渲染視圖也不可行,因爲它包含具有內部狀態的子視圖。只要將不相關的元素添加到集合中,此狀態就會丟失。 – 2014-09-24 07:11:49

+0

這些都是應該包含在您的問題中的所有重要細節。 – ncksllvn 2014-09-24 12:35:06