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("next") 和 getElement("prev") 之类的操作来询问我收藏中的下一个或上一个模型。getElement 返回的是实际模型,而不是索引。我知道collection.indexOf,但我想要一种方法来循环遍历集合,而无需先从模型开始。这个实现是否比它需要的更难?

4

4 回答 4

25

我会做这样的事情。请记住,当前没有任何错误处理,因此如果您当前位于集合中的第一个模型并尝试获取前一个模型,您可能会收到错误。

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();

为了更好地解释下一个/上一个是如何工作的。

// 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));
于 2012-04-18T02:41:06.823 回答
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);
    }
},
于 2013-07-30T13:43:01.450 回答
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();
于 2014-01-13T17:40:32.507 回答
0

我的主干 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);
    }
});
于 2015-04-12T06:38:04.020 回答