从集合中获取下一个和上一个模型

Sne*_*bat 15 backbone.js

我已经看到了从集合中获取下一个或上一个模型的几种不同方法,但是想知道是否有人可以就我决定实现它的方式提供一些建议.我的收藏是有序的,但我正在排序的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;
    };
  }
});
Run Code Online (Sandbox Code Playgroud)

当使用getElement时,我会执行诸如getElement("next")和getElement("prev")之类的事情来询问我的集合中的下一个或上一个模型.从getElement返回的是实际模型,而不是索引.我知道collection.indexOf,但我想要一种方法来循环一个集合,而无需先从模型开始.这种实施是否比它需要的更难?

abr*_*ham 24

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

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;
  }
});
Run Code Online (Sandbox Code Playgroud)

进入下一个模型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));
Run Code Online (Sandbox Code Playgroud)

  • 如果使用v0.9 +,则需要使用this.setElement(this.at(0)); 当前在创建集合后调用的initialize函数中.这是因为在Collection创建模型之前会调用initialize.例如:var myCollection = new MyCollection(data); myCollection.setElement(this.at(0)); (4认同)
  • 设置起始元素可以通过在重置事件上绑定init来完成.我是这样做的:`initialize:function(){this.bind('reset',this.init,this); },init:function(){this.setElement(this.at(0)); }` (3认同)

Tom*_*Tom 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);
    }
},
Run Code Online (Sandbox Code Playgroud)