2012-04-17 47 views
15

我已經看到了幾種不同的方式從集合中獲取下一個或以前的模型,但想知道是否有人可以提供一些建議,以便我決定實施它。我的收藏是有序的,但我排序的ID不保證是連續的。它只保證是唯一的。假設較小的ID是集合的「較舊」條目,較大的ID是「較新」。從集合中獲取下一個和以前的模型

MyCollection = Backbone.Collection.extend({ 
    model: MyModel, 
    initialize:function(){ 
    this.getElement = this._getElement(0); 
    }, 
    comparator: function(model) { 
    return model.get("id"); 
    }, 
    _getElement: function (index){ 
    var self = this; 
    return function (what){ 
    if (what === "next"){ 
     if (index+1 >= self.length) return null; 
     return self.at(++index); 
    } 
    if (what === "prev"){ 
     if (index-1 < 0) return null; 
     return self.at(--index); 
    } 
    // what doesn't equal anything useful 
    return null; 
    }; 
    } 
}); 

當使用getElement,我不喜歡的東西getElement(「下一步」)而getElement(「上一頁」),要求我的集合中的一個或下一個模型。從getElement返回的是實際模型,而不是索引。我知道關於collection.indexOf,但我想要一種方式來循環一個集合,而不需要先創建一個模型。這個實現比它需要的更難嗎?

回答

23

我會做這樣的事情。請記住,目前沒有任何錯誤處理,所以如果您當前處於集合中的第一個模型,並嘗試獲取之前的錯誤,您可能會遇到錯誤。

MyCollection = Backbone.Collection.extend({ 
    model: MyModel, 
    initialize:function(){ 
    this.bindAll(this); 
    this.setElement(this.at(0)); 
    }, 
    comparator: function(model) { 
    return model.get("id"); 
    }, 
    getElement: function() { 
    return this.currentElement; 
    }, 
    setElement: function(model) { 
    this.currentElement = model; 
    }, 
    next: function(){ 
    this.setElement(this.at(this.indexOf(this.getElement()) + 1)); 
    return this; 
    }, 
    prev: function() { 
    this.setElement(this.at(this.indexOf(this.getElement()) - 1)); 
    return this; 
    } 
}); 

要前進到下一個模型collection.next()。前進到下一個模型並返回它var m = collection.next().getElement();

更好地解釋next/prev如何工作。

// The current model 
this.getElement(); 
// Index of the current model in the collection 
this.indexOf(this.getElement()) 
// Get the model either one before or one after where the current model is in the collection 
this.at(this.indexOf(this.getElement()) + 1) 
// Set the new model as the current model 
this.setElement(this.at(this.indexOf(this.getElement()) + 1)); 
+0

我喜歡你的一些想法,特別是在初始化方法中使用this.at()。雖然你的代碼雖然很長。如果沒有其他人提出任何更好和/或更簡潔的建議,您將得到綠色檢查:-)我的方法更短,並且在到達任何一端時通過返回null來防止脫落到集合的末尾。 – 2012-04-18 16:52:42

+0

您可以通過拋棄'set/getElement'函數並直接訪問'currentElement'值來縮短它。 – abraham 2012-04-20 03:03:59

+4

如果使用v0.9 +,你需要有this.setElement(this.at(0));目前在創建集合之後調用的初始化函數中。這是因爲在Collection創建模型之前調用initialize。例如:var myCollection = new MyCollection(data); myCollection.setElement(this.at(0)); – 2012-07-17 01:43:00

6

我這樣做的方式稍有不同,因爲我將方法添加到模型而不是集合中。這樣,我可以抓住任何模型,並獲得序列中的下一個模型。

next: function() { 
    if (this.collection) { 
     return this.collection.at(this.collection.indexOf(this) + 1); 
    } 
}, 
prev: function() { 
    if (this.collection) { 
     return this.collection.at(this.collection.indexOf(this) - 1); 
    } 
}, 
+0

儘管我喜歡這種方法,但在實踐中還存在一些問題。 1.您需要將自定義的「集合」屬性添加到您的模型中,該模型引用了您要使用的特定集合。這假設你的模型只是一個集合的成員,但情況可能並非如此。骨幹的架構讓模型「在黑暗中」可以說是關於收集和觀看它的觀點,以確保鬆耦合和靈活性。 2.如果this.collection.indexOf(this)<= 0 ||,這些方法會拋出錯誤this.collection.indexOf(this)> = collection.size()。 – 1nfiniti 2014-01-13 17:50:34

+0

@mikeyUX我同意只能屬於一個集合可以是限制性的,那就是骨幹方式。我個人認爲在Backbone中應該有一些List實現,它只是用於模型'集合',但沒有所有服務器端的東西,所以你可以更容易地完成多個集合。 此外,你可以很容易地調換它,所以它是一個將模型作爲參數的集合方法:'''collection.next(model);''' 最後,這不會導致你提出的場景 - 它返回undefined,這是預期的! – Tom 2014-01-15 09:28:33

2

碰碰這個古老的線程有一個較爲通用的解決方案:

東西添加到Collection.prototype

current: null, 

initialize: function(){ 
    this.setCurrent(0); 
    // whatever else you want to do here... 
}, 

setCurrent: function(index){ 
    // ensure the requested index exists 
    if (index > -1 && index < this.size()) 
     this.current = this.at(index); 
    else 
     // handle error... 
}, 

// unnecessary, but if you want sugar... 
prev: function() { 
    this.setCurrent(this.at(this.current) -1); 
}, 
next: function() { 
    this.setCurrent(this.at(this.current) +1); 
} 

那麼你可以使用糖的方法來獲得分組/下一個型號像這樣...

collection.prev(); 
collection.next(); 
0

My Backbo ne SelectableCollection類:

Backbone.Collection.extend({ 
    selectNext: function() { 
     if(this.cursor < this.length - 1) { 
      this.cursor++; 
      this.selected = this.at(this.cursor); 
      this.trigger('selected', this.selected); 
     } 
    }, 

    selectPrevious: function() { 
     if(this.cursor > 0) { 
      this.cursor--; 
      this.selected = this.at(this.cursor); 
      this.trigger('selected', this.selected); 
     } 
    }, 
    selectById: function (id) { 
     this.selected = this.get(id); 
     this.cursor = this.indexOf(this.selected); 
     this.trigger('selected', this.selected); 
    }, 
    unselect: function() { 
     this.cursor = null; 
     this.selected = null; 
     this.trigger('selected', null); 
    } 
}); 
相關問題