admin管理员组

文章数量:1389750

I make my first backbone app and get some problems with collection sorting. After using this

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

console.log(SortedFriends) show that SortedFriends contains sorted models, but when i try to use collection functions like 'SortedFriends.each' or 'SortedFriends.at' it make error:

TypeError: SortedFriends.each is not a function.

Code:

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

I make my first backbone app and get some problems with collection sorting. After using this

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

console.log(SortedFriends) show that SortedFriends contains sorted models, but when i try to use collection functions like 'SortedFriends.each' or 'SortedFriends.at' it make error:

TypeError: SortedFriends.each is not a function.

Code:

  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);            
    });
Share Improve this question edited Mar 11, 2014 at 16:26 McGarnagle 103k31 gold badges234 silver badges261 bronze badges asked Aug 2, 2013 at 7:03 fyodorfyodor 411 silver badge2 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

If youre using backbone collections then youre probably better off using the parator rather than collection methods

http://backbonejs/#Collection-parator

When youre ready to sort your collection:

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

OR if you want to keep the order of the unsorted collection then you will need to clone it first

http://backbonejs/#Collection-clone

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

I'm not sure if it's a bug or a feature of Backbone's adaptation of sortBy, but apparently it returns an array, not an Underscore collection.

One workaround is to wrap the whole thing in _( ... ), which tells Underscore to wrap the array back into a collection:

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

Edit

Most of the Underscore methods in Backbone seem to be chainable (replace sortBy with reject, for example, and it runs). Looking at the Backbone source where they wire up the Underscore proxies, it seems that sortBy is treated differently. I can't understand why they do it this way ...

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

本文标签: javascriptBackbone collection sortByStack Overflow