Получение следующей и предыдущей модели из коллекции
Я видел несколько разных способов получить следующую или предыдущую модель из коллекции, но задавался вопросом, может ли кто-нибудь предложить некоторые советы по тому, как я решил ее реализовать. Моя коллекция упорядочена, но идентификатор, который я сортирую, не гарантированно будет последовательным. Он гарантированно будет уникальным. Предположим, что меньшие идентификаторы являются "более старыми" элементами коллекции, а большие идентификаторы "более новые".
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 ( "next" ) и getElement ( "prev" ), чтобы попросить следующую или предыдущую модель в моей коллекции. То, что возвращается из getElement, является фактической моделью, а не индексом. Я знаю о collection.indexOf, но мне нужен способ прокрутки коллекции без предварительного запуска модели. Является ли эта реализация сложнее, чем она должна быть?
Ответы
Ответ 1
Я бы сделал что-то вроде этого. Имейте в виду, что в настоящее время нет никакой обработки ошибок, поэтому, если вы в настоящий момент находитесь в первой модели в коллекции и пытаетесь получить предыдущую версию, вы, вероятно, получите сообщение об ошибке.
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();
Чтобы объяснить немного лучше, как работает следующий /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));
Ответ 2
Я сделал это несколько иначе, потому что добавляю методы к модели, а не к коллекции. Таким образом, я могу захватить любую модель и получить следующую в последовательности.
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);
}
},
Ответ 3
Накидывая эту старую нить несколько более общим решением:
Материал для добавления в 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();
Ответ 4
My Backbone 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);
}
});