Skip to content

Commit

Permalink
Refactor serializeData to no longer use toJSON.
Browse files Browse the repository at this point in the history
toJSON should only be used for preparing data to be sent to the
server. In addition, serializeData no longer accepts arguments,
distinguishing it further from templateHelpers.

Resolves #1476
  • Loading branch information
jamesplease committed Jan 7, 2015
1 parent 26454ed commit 64771ee
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 51 deletions.
16 changes: 3 additions & 13 deletions src/composite-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,9 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
return childView;
},

// Serialize the model for the view.
// You can override the `serializeData` method in your own view
// definition, to provide custom serialization for your view's data.
// Return the serialized model
serializeData: function() {
var data = {};

if (this.model){
data = _.partial(this.serializeModel, this.model).apply(this, arguments);
}

return data;
return this.serializeModel();
},

// Renders the model and the collection.
Expand All @@ -83,9 +75,7 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
// Render the root template that the children
// views are appended to
_renderTemplate: function() {
var data = {};
data = this.serializeData();
data = this.mixinTemplateHelpers(data);
var data = this.mixinTemplateHelpers(this.serializeData());

this.triggerMethod('before:render:template');

Expand Down
43 changes: 22 additions & 21 deletions src/item-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,36 @@ Marionette.ItemView = Marionette.View.extend({
Marionette.View.apply(this, arguments);
},

// Serialize the model or collection for the view. If a model is
// found, the view's `serializeModel` is called. If a collection is found,
// each model in the collection is serialized by calling
// the view's `serializeCollection` and put into an `items` array in
// the resulting data. If both are found, defaults to the model.
// You can override the `serializeData` method in your own view definition,
// to provide custom serialization for your view's data.
serializeData: function(){
if (!this.model && !this.collection) {
return {};
}
// Serialize the view's model *or* collection, if
// it exists, for the template
serializeData: function() {

var args = [this.model || this.collection];
if (arguments.length) {
args.push.apply(args, arguments);
// If we have a model, we serialize that
if (this.model) {
return this.serializeModel();
}

if (this.model) {
return this.serializeModel.apply(this, args);
} else {
// Otherwise, we serialize the collection,
// making it available under the `items` property
else if (this.collection) {
return {
items: this.serializeCollection.apply(this, args)
items: this.serializeCollection()
};
}

// If we have neither, we return an empty object
else {
return {};
}
},

// Serialize a collection by serializing each of its models.
serializeCollection: function(collection){
return collection.toJSON.apply(collection, _.rest(arguments));
// Serialize a collection by cloning each of
// its model's attributes
serializeCollection: function() {
if (!this.collection) { return {}; }
return this.collection.map(function(model) {
return _.clone(model.attributes);
});
},

// Render the view, defaulting to underscore.js templates.
Expand Down
11 changes: 7 additions & 4 deletions src/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ Marionette.View = Backbone.View.extend({
return this.getOption('template');
},

// Serialize a model by returning its attributes. Clones
// the attributes to allow modification.
serializeModel: function(model){
return model.toJSON.apply(model, _.rest(arguments));
// Prepares the special `model` property of a view
// for being displayed in the template. By default
// we simply clone the attributes. Override this if
// you need a custom transformation for your view's model
serializeModel: function() {
if (!this.model) { return {}; }
return _.clone(this.model.attributes);
},

// Mix in template helper methods. Looks for a
Expand Down
2 changes: 1 addition & 1 deletion test/unit/composite-view.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ describe('composite view', function() {
this.view.serializeData();
});

it("should call serializeModel", function(){
it("should call serializeModel", function() {
expect(this.view.serializeModel).to.have.been.calledOnce;
});
});
Expand Down
12 changes: 2 additions & 10 deletions test/unit/item-view.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,17 +310,13 @@ describe('item view', function() {
describe('and the view only has a collection', function() {
beforeEach(function() {
this.itemView.collection = new Backbone.Collection(this.collectionData);
this.itemView.serializeData(1, 2, 3);
this.itemView.serializeData();
});

it("should call serializeCollection", function(){
expect(this.itemView.serializeCollection).to.have.been.calledOnce;
});

it('and the serialize function should be called with the provided arguments', function() {
expect(this.itemView.serializeCollection).to.have.been.calledWith(this.itemView.collection, 1, 2, 3);
});

it("should not call serializeModel", function() {
expect(this.itemView.serializeModel).to.not.have.been.called;
});
Expand All @@ -330,17 +326,13 @@ describe('item view', function() {
beforeEach(function() {
this.itemView.model = new Backbone.Model(this.modelData);
this.itemView.collection = new Backbone.Collection(this.collectionData);
this.itemView.serializeData(1, 2, 3);
this.itemView.serializeData();
});

it("should call serializeModel", function() {
expect(this.itemView.serializeModel).to.have.been.calledOnce;
});

it('and the serialize function should be called with the provided arguments', function() {
expect(this.itemView.serializeModel).to.have.been.calledWith(this.itemView.model, 1, 2, 3);
});

it('should not call serializeCollection', function() {
expect(this.itemView.serializeCollection).to.not.have.been.called;
});
Expand Down
6 changes: 4 additions & 2 deletions test/unit/view.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,13 @@ describe('base view', function() {

beforeEach(function(){
model = new Backbone.Model(modelData);
view = new Marionette.View();
view = new Marionette.View({
model: model
});
});

it("should return all attributes", function(){
expect(view.serializeModel(model)).to.be.eql(modelData);
expect(view.serializeModel()).to.be.eql(modelData);
});
});
});

0 comments on commit 64771ee

Please sign in to comment.