diff --git a/backbone.js b/backbone.js index d47293ac..b1985967 100644 --- a/backbone.js +++ b/backbone.js @@ -733,12 +733,13 @@ sort: function(options) { options || (options = {}); if (!this.comparator) throw new Error('Cannot sort a set without a comparator'); - if (typeof this.comparator === "string"){ - var attrName = this.comparator; - this.comparator = function(o){ - return o.get(attrName); - }; + + // If provided an attribute name, use it to sort the collection. + if (_.isString(this.comparator)) { + var attr = this.comparator; + this.comparator = function(model){ return model.get(attr); }; } + var boundComparator = _.bind(this.comparator, this); if (this.comparator.length === 1) { this.models = this.sortBy(boundComparator); diff --git a/index.html b/index.html index 2c555b63..f77acc2b 100644 --- a/index.html +++ b/index.html @@ -1590,33 +1590,30 @@ var book = Library.get(110);

comparatorcollection.comparator
- By default there is no comparator on a collection. + By default there is no comparator for a collection. If you define a comparator, it will be used to maintain the collection in sorted order. This means that as models are added, they are inserted at the correct index in collection.models. - Comparators come in three different forms: + A comparator can be defined as a + sortBy + (pass a function that takes a single argument), + as a + sort + (pass a comparator function that expects two arguments), + or as a string indicating the attribute to sort by. +

+ +

+ "sortBy" comparator functions take a model and return a numeric or string + value by which the model should be ordered relative to others. + "sort" comparator functions take two models, and return -1 if + the first model should come before the second, 0 if they are of + the same rank and 1 if the first model should come after.

-

Note how even though all of the chapters in this example are added backwards, - they come out in the proper order thanks to the comparator: + they come out in the proper order:

@@ -1634,25 +1631,6 @@ chapters.add(new Chapter({page: 1, title: "The Beginning"}));
 alert(chapters.pluck('title'));
 
-

- As no special computation was done on the model attribute, the previous example also works - with a comparator string naming the desired sorting attribute: -

- -
-var Chapter  = Backbone.Model;
-var chapters = new Backbone.Collection;
-
-chapters.comparator = "page";
-
-chapters.add(new Chapter({page: 9, title: "The End"}));
-chapters.add(new Chapter({page: 5, title: "The Middle"}));
-chapters.add(new Chapter({page: 1, title: "The Beginning"}));
-
-alert(chapters.pluck('title'));
-
-
-

Collections with a comparator will not automatically re-sort if you later change model attributes, so you may wish to call diff --git a/test/collection.js b/test/collection.js index d3f9fc52..123aeb3c 100644 --- a/test/collection.js +++ b/test/collection.js @@ -18,7 +18,7 @@ $(document).ready(function() { })); - test("new and sort", 9, function() { + test("new and sort", 7, function() { equal(col.first(), a, "a should be first"); equal(col.last(), d, "d should be last"); col.comparator = function(a, b) { @@ -32,11 +32,15 @@ $(document).ready(function() { equal(col.first(), d, "d should be first"); equal(col.last(), a, "a should be last"); equal(col.length, 4); - // tests with string comparator - col.comparator = "label"; - col.sort(); - equal(col.first(), a, "a should be first"); - equal(col.last(), d, "d should be last"); + }); + + test("String comparator.", 1, function() { + var collection = new Backbone.Collection([ + {id: 3}, + {id: 1}, + {id: 2} + ], {comparator: 'id'}); + deepEqual(collection.pluck('id'), [1, 2, 3]); }); test("new and parse", 3, function() {