2015-02-10 22 views
0

我無法讓Backbone集合正確排序。我繼承了這個項目,所以在其他地方可能會出現一些錯誤,但我想排除我的任何語法錯誤。骨幹菜單沒有排序

該項目使用JSON文件來處理數據:

"classifications": [ 
      { 
       "name": "1 Bedroom", 
       "alias": "1BR", 
       "id": "1BR", 
       "menu_desc": "Residences" 
      }, 
      { 
       "name": "2 Bedroom", 
       "alias": "2BR", 
       "id": "2BR", 
       "menu_desc": "Residences" 
      }, 
      { 
       "name": "3 Bedroom", 
       "alias": "3BR", 
       "id": "3BR", 
       "menu_desc": "Residences" 
      }, 
      { 
       "name": "4 Bedroom", 
       "alias": "4BR", 
       "id": "4BR", 
       "menu_desc": "Residences" 
      }, 
      { 
       "name": "Common Areas", 
       "alias": "Common", 
       "id": "Common", 
       "menu_desc": "Resident Amenities" 
      } 
     ] 

此前,沒有一個房單位,以及它呈現的是這樣的順序:

original order

我加了一個房間的分類,突然這個訂單是這樣的:

incorrect order

我做了一些挖掘並找到關於比較器屬性的文檔,但它似乎只適用於集合。該項目不使用集合進行分類。它適用於子菜單項目(單元所在的地板等),但不是主菜單:

var MenuClassificationListView = Backbone.View.extend({ 
    id: "classification_accordion", 
    template: _.template("<% var classifications = this.options.classifications; _.each(this.collection.attributes, function(v,k) { %>"+ 
             "<h3 class='<%= k %>'><%= classifications.get(k).get('name') %>"+ 
             "<p><%=classifications.get(k).get('menu_desc')%></p></h3>"+ 
             "<% var model = new MenuClassificationList(v); var view = new MenuClassificationItemView({collection:model, classification:k}); %>"+ 
             "<% print(view.render().el.outerHTML); %>"+ 
           "<% }); "+ 
          "%>"), 
    render: function(){ 
     //console.log(this.options.classifications); 
     //console.log(this.collection.attributes); 
     //alert(1); 
     this.$el.html(this.template()); 
     return this; 

    } 

}); 

如何合併比較器?

感謝,

TY

回答

1

的一種方法是定義一個集合的分類,相同的方式,他們都爲你所提到的其他項目定義:

var Classifications = Backbone.Collections.extend({ // etc. etc. 

這樣你可以添加比較器,它將始終被排序。

另一種方式是進行排序(http://underscorejs.org/#sortBy)在視圖中initialize功能數組:

initialize: function(options) { // sorry don't remember the exact syntax for the parameters passed in, but I believe options is what you need 
    this.options.sortedclassifications = _sortBy(options.classifications, function (c) { return parseInt(c.id); }); // or any other sorting logic 
} 

然後在template使用排序分類:

template: _.template("<% var classifications = this.options.sortedclassifications; _.each(this.collection.attributes, function(v,k) { %>" + // etc. etc. 

這應該能給你帶來什麼你需要。但是,如果我可以添加個人意見,我會盡力爲分類定義一個集合,併爲單個分類定義一個模型。此外,我會保留MenuClassificationListView,但也會創建一個MenuClassificationView,它將保存單個分類模板。

通過這種方式,您可以組合視圖,更改單個分類的渲染而不更改列表並將事件範圍限制在內部視圖(因此單擊單個分類由單個分類視圖處理)。在我看來,它使得一切都變得更清潔,更加可組合和可讀。

0

_.sortBy不需要使用,因爲Backbone集合已經內置了排序功能。

參見:http://backbonejs.org/#Collection-comparator

例子:

var SortedCollection = Backbone.Collection.extend({ 
    comparator: 'key' 
}); 

var mySortedCollection = new SortedCollection([{a:5, key:2}, {key:1}]); 

console.log(mySortedCollection.toJSON()); 
// [{key:1}, {a:5, key:2}] 

然而,收集將不會自動改變密鑰屬性時重新排序。請參閱:

mySortedCollection.at(0).set('key', 3); 

console.log(mySortedCollection.toJSON()); 
// [{key:3}, {a:5, key:2}] 

你有多種選擇來解決這個問題:你可以手動調用mySortedCollection.sort()或者您也可以通過其change:key事件綁定重新排序的集合初始化集合。 change:key事件由鍵屬性更改的模型觸發。該事件會自動傳播到集合中。

var AutoSortedCollection = Backbone.Collection.extend({ 
    comparator: 'key', 
    initialize: function() { 
     this.listenTo(this, 'change:key', this.sort); 
    } 
}); 

此外,我建議從模板中刪除功能。調試Backbone Views很容易,但當您在模板字符串內移動功能時,讀取堆棧軌跡變得更加困難。您還可以通過使用Backbone View來準備所有的演示數據,並將模板顯示出來,從而對問題進行適當的分離。

var MyView = Backbone.View.extend({ 
    //... 
    serializeData: function() { 
     return { 
      classifications: this.collection.toJSON(), 
      keys: this.collection.length > 0 ? this.collection.at(0).keys() : [] 
     }; // already sorted 
    } 
    render: function() { 
     this.$el.html(this.template(this.serializeData())); 
    } 
}); 

你的模板字符串變得更容易閱讀:您可以直接使用變量classificationskeys,與_.each對他們的迭代和簡單的參考值,而不必處理集合語法。