I've seen a few different ways to get the next or previous model from a collection, but was wondering if anyone could offer some advice on the way I decided to implement it. My collection is ordered, but the id that i'm sorting on is not guaranteed to be sequential. It's only guaranteed to be unique. Assume that smaller ids are "older" entries to the collection and larger ids are "newer".
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;
};
}
});
When using getElement, I do things like getElement("next") and getElement("prev") to ask for the next or previous model in my collection. What is returned from getElement is the actual model, not the index. I know about collection.indexOf, but I wanted a way to loop through a collection without first having a model to start from. Is this implementation harder than it needs to be?
I would do something like this. Keep in mind that there isn't any error handling currently so if you are currently at the first model in the collection and try to get the previous you will probably get an error.
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;
}
});
To progress to the next model collection.next()
. To progress to the next model and return it var m = collection.next().getElement();
To explain a little better how next/prev works.
// 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));
I've done this slightly differently in that I'm adding the methods to the model rather than to the collection. That way, I can grab any model, and get the next one in the sequence.
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);
}
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With