骨干集合sortBy

时间:2013-08-02 07:03:43

标签: javascript backbone.js underscore.js

我制作了我的第一个骨干应用程序并且在收集排序时遇到了一些问题。 使用后

var SortedFriends = MyFriends.sortBy(function(friend) {
          return friend.get("uid");
        });  

console.log(SortedFriends)显示SortedFriends包含已排序的模型,但是当我尝试使用“SortedFriends.each”或“SortedFriends.at”等集合函数时,会出错:

TypeError:SortedFriends.each不是函数。

代码:

  var Friend = Backbone.Model.extend({});          
      var Friends = Backbone.Collection.extend({
        model: Friend,            
      });  

      var MyFriends = new Friends();
      MyFriends.reset(<?=$friends?>);

      var FriendView = Backbone.View.extend({
          initialize: function(){
              model:Friend            
          },              
          tagName: "tr",
          template: _.template($('#item-template').html()),
          className: "document-row",          
          render: function() {                              

         this.$el.html(this.template(this.model.toJSON()));                            
              return this;             
          }          
      });     


    var SortedFriends = MyFriends.sortBy(function(friend) {
      return friend.get("uid");
    });          

    var addOne = function(element){           
        var view = new FriendView({model: element});
        $("#friends").append(view.render().el);
    }                              
    console.log(JSON.stringify(SortedFriends));
    SortedFriends.each(function(friend){
        var view = new FriendView({model: friend});
        $("#friends").append(view.render().el);            
    });

2 个答案:

答案 0 :(得分:3)

如果您使用主干集合,那么最好使用comparator而不是收集方法

http://backbonejs.org/#Collection-comparator

当您准备好对收藏品进行排序时:

MyFriends.comparator = function(friend){
   return friend.get("uid");
});
MyFriends.sort();

或者如果你想保留未分类集合的顺序,那么你需要先克隆它

http://backbonejs.org/#Collection-clone

var SortedFriends = MyFriends.clone();
SortedFriends.comparator = function(friend){
   return friend.get("uid");
});
SortedFriends.sort();

答案 1 :(得分:2)

我不确定它是否是Backbone改编sortBy的错误或特征,但显然它返回一个数组,而不是Underscore集合。

一个解决方法是将整个事物包装在_( ... )中,告诉Underscore将数组包装回集合中:

var SortedFriends = _(MyFriends.sortBy(function(friend) {
  return friend.get("uid");
}));

修改

Backbone中的大多数Underscore方法似乎都是可链接的(例如,将sortBy替换为reject并运行)。查看他们连接Underscore代理的Backbone源,似乎sortBy的处理方式不同。我不明白为什么他们这样做......

var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
    'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
    'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
    'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
    'tail', 'drop', 'last', 'without', 'indexOf', 'shuffle', 'lastIndexOf',
    'isEmpty', 'chain'];

_.each(methods, function(method) {
    Collection.prototype[method] = function() {
      var args = slice.call(arguments);
      args.unshift(this.models);
      return _[method].apply(_, args);
    };
});

var attributeMethods = ['groupBy', 'countBy', 'sortBy'];

_.each(attributeMethods, function(method) {
    Collection.prototype[method] = function(value, context) {
      var iterator = _.isFunction(value) ? value : function(model) {
        return model.get(value);
      };
      return _[method](this.models, iterator, context);
};