diff --git a/src/composite-view.js b/src/composite-view.js index 5bcfebca7e..3d73517a03 100644 --- a/src/composite-view.js +++ b/src/composite-view.js @@ -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. @@ -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'); diff --git a/src/item-view.js b/src/item-view.js index ca192eed54..45f68ae25f 100644 --- a/src/item-view.js +++ b/src/item-view.js @@ -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. diff --git a/src/view.js b/src/view.js index 269d40a7c7..11da87ccd2 100644 --- a/src/view.js +++ b/src/view.js @@ -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 diff --git a/test/unit/composite-view.spec.js b/test/unit/composite-view.spec.js index 083142a9db..64f9cddda6 100644 --- a/test/unit/composite-view.spec.js +++ b/test/unit/composite-view.spec.js @@ -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; }); }); diff --git a/test/unit/item-view.spec.js b/test/unit/item-view.spec.js index 0b5bdd2b6b..3fa603bc38 100644 --- a/test/unit/item-view.spec.js +++ b/test/unit/item-view.spec.js @@ -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; }); @@ -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; }); diff --git a/test/unit/view.spec.js b/test/unit/view.spec.js index 2d0c73d7d7..fe6d0b00ef 100644 --- a/test/unit/view.spec.js +++ b/test/unit/view.spec.js @@ -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); }); }); });