Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Backbone.js 从集合中获取下一个和上一个模型_Backbone.js - Fatal编程技术网

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

Backbone.js 从集合中获取下一个和上一个模型,backbone.js,Backbone.js,我已经看到了一些从集合中获取下一个或上一个模型的不同方法,但是我想知道是否有人可以就我决定实现它的方式提供一些建议。我的集合已排序,但我正在排序的id不能保证是连续的。它只保证是独一无二的。假设较小的ID是集合中的“旧”项,较大的ID是“新”项 MyCollection=Backbone.Collection.extend({ 型号:MyModel, 初始化:函数(){ this.getElement=this.\u getElement(0); }, 比较器:功能(模型){ 返回模型。获取(“

我已经看到了一些从集合中获取下一个或上一个模型的不同方法,但是我想知道是否有人可以就我决定实现它的方式提供一些建议。我的集合已排序,但我正在排序的id不能保证是连续的。它只保证是独一无二的。假设较小的ID是集合中的“旧”项,较大的ID是“新”项

MyCollection=Backbone.Collection.extend({
型号:MyModel,
初始化:函数(){
this.getElement=this.\u getElement(0);
},
比较器:功能(模型){
返回模型。获取(“id”);
},
_getElement:函数(索引){
var self=这个;
返回函数(什么){
如果(什么==“下一步”){
if(index+1>=self.length)返回null;
返回自.at(++索引);
}
如果(什么==“上一个”){
如果(索引-1<0)返回null;
在(--指数)处返回自身;
}
//什么不等于什么有用的东西
返回null;
};
}
});

使用getElement时,我会执行诸如getElement(“next”)和getElement(“prev”)之类的操作来请求集合中的下一个或上一个模型。从getElement返回的是实际的模型,而不是索引。我知道collection.indexOf,但我想找到一种在集合中循环的方法,而不必首先从一个模型开始。这个实现比需要的更难吗?

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

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

我的做法略有不同,因为我将方法添加到模型中,而不是集合中。这样,我可以抓取任何模型,然后得到序列中的下一个

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);
    }
},

用一个更通用的解决方案替换这个旧线程:

要添加到集合中的内容。原型

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

我的主干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);
    }
});
Backbone.Collection.extend({
选择下一步:函数(){
if(this.cursor0){
这个光标--;
this.selected=this.at(this.cursor);
this.trigger('selected',this.selected);
}
},
selectById:功能(id){
this.selected=this.get(id);
this.cursor=this.indexOf(this.selected);
this.trigger('selected',this.selected);
},
取消选择:函数(){
this.cursor=null;
this.selected=null;
this.trigger('selected',null);
}
});

我喜欢你的一些想法,特别是在initialize方法中使用这个.at()。不过,您的代码相当长。如果没有其他人提出更好和/或更简洁的建议,您将获得绿色复选框:-)我的方法更短,并且在到达集合的任一端时返回null,从而防止从集合的末尾脱落。您可以通过放弃
set/getElement
函数并直接访问
currentElement
值来缩短它。如果使用v0.9+,则需要使用此.setElement(此.at(0))); 当前在创建集合后调用的初始化函数中。这是因为在集合创建模型之前会调用initialize。e、 g.:var myCollection=新的myCollection(数据);myCollection.setElement(此.at(0));正如Denis所说,此解决方案不再适用于backbon 0.9+,您需要在初始化后以某种方式设置起始元素。可以通过在重置事件上绑定init来设置起始元素。我是这样做的:
initialize:function(){this.bind('reset',this.init,this);},init:function(){this.setElement(this.at(0));},
虽然我喜欢这种方法,但在实践中存在一些问题。1.您需要向模型添加一个自定义“集合”属性,该属性引用要使用的特定集合。这假设您的模型只是单个集合的一个成员,情况可能并非如此。主干网的体系结构使模型“处于黑暗中”,可以说,是关于监视模型的集合和视图,以确保松散耦合和灵活性。2.如果this.collection.indexOf(this)=collection.size(),这些方法将抛出错误。@mikeyUX我同意,只能属于单个集合可能会受到限制,这是主干方式。我个人认为主干网中应该有一些列表实现,只用于模型“集合”,而不需要所有服务器端的东西,因此您可以更轻松地执行多个集合之类的操作。此外,您还可以轻松地交换它,使其成为集合上以模型作为参数的方法:
collection.next(model)最后,这不会在您建议的场景中导致错误-它返回未定义的,这是预期的!
collection.prev();
collection.next();
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);
    }
});