Skip to content

Commit

Permalink
Merge pull request #3644 from jridgewell/collection-parse
Browse files Browse the repository at this point in the history
Collection parse
  • Loading branch information
jashkenas committed Jun 2, 2015
2 parents 5ea1585 + 13de636 commit ff57b54
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 60 deletions.
10 changes: 5 additions & 5 deletions backbone.js
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,7 @@
if (options.comparator !== void 0) this.comparator = options.comparator;
this._reset();
this.initialize.apply(this, arguments);
if (models && options.parse) models = this.parse(models, options);
if (models) this.reset(models, _.extend({silent: true}, options));
};

Expand Down Expand Up @@ -789,7 +790,6 @@
// the core operation for updating the data contained by the collection.
set: function(models, options) {
options = _.defaults({}, options, setOptions);
if (options.parse) models = this.parse(models, options);
var singular = !_.isArray(models);
models = singular ? (models ? [models] : []) : models.slice();
var id, model, attrs, existing, sort;
Expand Down Expand Up @@ -983,13 +983,13 @@
// collection when they arrive. If `reset: true` is passed, the response
// data will be passed through the `reset` method instead of `set`.
fetch: function(options) {
options = options ? _.clone(options) : {};
if (options.parse === void 0) options.parse = true;
var success = options.success;
options = _.extend({parse: true}, options);
var collection = this;
var success = options.success;
options.success = function(resp) {
var method = options.reset ? 'reset' : 'set';
collection[method](resp, options);
var models = options.parse ? collection.parse(resp, options) : resp;
collection[method](models, options);
if (success) success.call(options.context, collection, resp, options);
collection.trigger('sync', collection, resp, options);
};
Expand Down
123 changes: 68 additions & 55 deletions test/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,19 +252,6 @@
equal(col.at(0).get('value'), 2);
});

test("add with parse and merge", function() {
var collection = new Backbone.Collection();
collection.parse = function(attrs) {
return _.map(attrs, function(model) {
if (model.model) return model.model;
return model;
});
};
collection.add({id: 1});
collection.add({model: {id: 1, name: 'Alf'}}, {parse: true, merge: true});
equal(collection.first().get('name'), 'Alf');
});

test("add model to collection with sort()-style comparator", 3, function() {
var col = new Backbone.Collection;
col.comparator = function(a, b) {
Expand Down Expand Up @@ -978,29 +965,6 @@
equal(c.at(0).get('name'), 'test');
});

test("#1407 parse option on reset parses collection and models", 2, function() {
var model = {
namespace : [{id: 1}, {id:2}]
};
var Collection = Backbone.Collection.extend({
model: Backbone.Model.extend({
parse: function(model) {
model.name = 'test';
return model;
}
}),
parse: function(model) {
return model.namespace;
}
});
var c = new Collection();
c.reset(model, {parse:true});

equal(c.length, 2);
equal(c.at(0).get('name'), 'test');
});


test("Reset includes previous models in triggered event.", 1, function() {
var model = new Backbone.Model();
var collection = new Backbone.Collection([model])
Expand Down Expand Up @@ -1123,18 +1087,21 @@
});

test("`set` and model level `parse`", function() {
var Model = Backbone.Model.extend({});
var Model = Backbone.Model.extend({
parse: function(model) {
return model.model;
}
});
var Collection = Backbone.Collection.extend({
model: Model,
parse: function (res) { return _.pluck(res.models, 'model'); }
model: Model
});
var model = new Model({id: 1});
var collection = new Collection(model);
collection.set({models: [
{model: {id: 1}},
{model: {id: 2}}
]}, {parse: true});
equal(collection.first(), model);
collection.set([
{model: {id: 1, attr: 'test'}},
{model: {id: 2, attr: 'test'}}
], {parse: true});
deepEqual(collection.pluck('attr'), ['test', 'test']);
});

test("`set` data is only parsed once", function() {
Expand Down Expand Up @@ -1200,17 +1167,6 @@
new Collection().add({id: 1}, {sort: false});
});

test("#1915 - `parse` data in the right order in `set`", function() {
var collection = new (Backbone.Collection.extend({
parse: function (data) {
strictEqual(data.status, 'ok');
return data.data;
}
}));
var res = {status: 'ok', data:[{id: 1}]};
collection.set(res, {parse: true});
});

asyncTest("#1939 - `parse` is passed `options`", 1, function () {
var collection = new (Backbone.Collection.extend({
url: '/',
Expand Down Expand Up @@ -1622,4 +1578,61 @@
collection.invoke('method', 1, 2, 3);
});

test("set, add, and reset do not parse at collection level", 0, function() {
var Collection = Backbone.Collection.extend({
parse: function(models) {
ok(false);
}
});
var c = new Collection();
c.set({id: 1}, {parse: true});
c.add([{id: 2}, {id: 3}], {parse: true});
c.reset([{id: 4}, {id: 5}], {parse: true});
});

test("#3636 - create does not parse at collection level", 4, function() {
var Collection = Backbone.Collection.extend({
url: '/test',
model: Backbone.Model.extend({
parse: function(model) {
ok(true);
return model.model;
}
}),
parse: function(models) {
ok(false);
}
});
var c = new Collection();
c.create({}, {parse: true});
this.ajaxSettings.success({model: {id: 1}});
c.create(c.first(), {parse: true});
this.ajaxSettings.success({model: {attr: 'test'}});
equal(c.get(1).get('attr'), 'test');
});

test("fetch data is only parsed once", 3, function() {
var modelParse = 0;
var collectionParse = 0;
var Collection = Backbone.Collection.extend({
url: '/test',
model: Backbone.Model.extend({
parse: function(model) {
modelParse++;
return model.model;
}
}),
parse: function(models) {
collectionParse++;
return models.models;
}
});
var c = new Collection();
c.fetch();
this.ajaxSettings.success({models: [{model: {id: 1, attr: 'test'} }] });
equal(modelParse, 1);
equal(collectionParse, 1);
equal(c.get(1).get('attr'), 'test');
});

})();

0 comments on commit ff57b54

Please sign in to comment.