Search code examples
javascriptbackbone.js

Backbone Collection.create() with arbitrary parameters


I'm using Backbone with RESTful persistence.

Is it possible to define some arbitrary input parameters for a Backbone Collection create() method? Normally, Backbone expects corresponding model as input parameter.

Example:

Model "Adder" has the following attributes: "id", "date" and "sum"

I would like to create an instance of these model (via corresponding collections' create() method) by passing 3 parameters: a, b, c. Backend would then calculate the sum=a+b+c and create a record with a calculated sum. It should return a valid Model object and add it to collection.

So...

POST api/adder 1, 2, 3

Retured JSON:

{
    "id": 153235,
    "date": "11/11/11",
    "sum": 6
}

UPDATE:

Maybe will this, less extreme eample help. How can I send additional parameters to a POST method, besider the model's atts?

If a model is:

{
   a: 1,
   b: 2,
   c:3
}

I would like to send one parameter more, something like calculation_mode, that does not exist in the model itself.

Can I do that?


Solution

  • It sounds to me like your problem is that you need computed parameters stored and altered on the client-side that you don't necessarily want sent to the server through your POST and PUT requests. Essentially you want to save / create a subset of your model attributes.

    For this situation, a good pattern is to define a serverAttrs property in your model - a hash of attributes that represents the properties you want to persist to the server.

    You can then override Backbone's save method in your model or in a Base Model that your model extends from (a better approach).

    var MyModel = Backbone.Model.extend({
    
        idAttribute: 'id',
    
        serverAttrs: [
            'id',
            'label',
            'fullName',
        ],
    
        defaults: {
            label: 'My Default Label',
            fullName: '',
            firstName: 'John',
            lastName: 'Smith'
        },
    
        initialize: function(options){
            this.updateFullName();
    
            this.on('change:firstName change:lastName', this.updateFullName);
        },
    
        updateFullName: function(){
            this.set('fullName', this.get('firstName') + ' ' + this.get('lastName'));
        },
    
        save: function(attrs, options) {
            attrs = attrs || this.toJSON();
            options = options || {};
    
            if (this.serverAttrs) {
                attrs = _.pick(attrs, this.serverAttrs);
            }
    
            return Backbone.Model.prototype.save.call(this, attrs, options);
        }
    
    });
    

    In our save method we check for the existence of the serverAttrs property, if it exists we pluck out only those attributes and persist them to the server.

    So, in conclusion - you can store whatever attributes you want in your model (within reason) and then send only the attributes you want persisted to the server by defining a serverAttrs property.