Aidan Ewen
Aidan Ewen

Reputation: 13328

Declaring variables on a backbone model without setting defaults

I'm just starting out with backbone.js and I'm looking for a way of declaring fields on a model without having to provide defaults. It's really just for reference, so that when I start creating instances, I can see what fields I need to initialize.

With something like java I'd write

public class CartLine{
    StockItem stockItem;
    int quantity;

    public int getPrice(){
        return stockItem.getPrice() * quantity;
    }

    public int getStockID(){
        //
    }
}

However with backbone models, I'm referencing the fields in my method's but I'm not actually declaring them - It looks like I could easily create a CartLine object that doesn't contain a stockItem attribute or a quantity attribute. It feels strange not to mention the fields when I declare the object. Particularly as the object is supposed to represent an entity on the server.

var CartLine = Backbone.Model.extend({

  getStockID: function(){
    return this.stockItem.id;
  },

  getTotalPrice: function() {
    return this.quantity * this.StockItem.get('price');
  }
});

I guess I can add some sort of reference by using validate -

CartLine.validate = function(attrs){
  if (!(attrs.stockItem instanceof StockItem)){
    return "No Valid StockItem set";
  }
  if (typeof attrs.quantity !== 'number'){
    return "No quantity set";
  }
}

But my question is - am I missing something? Is there an established pattern for this?

Upvotes: 3

Views: 3330

Answers (1)

Kato
Kato

Reputation: 40582

The defaults are really for "fields" or data that is transferred back and forth from the server as part of the json.

If you just want to create some member variables as part of the Model, which are proprietary and not going to be sent back and forth to the server, then you can declare them a) on the object itself or b) in the initialize method (called during construction), and they can be passed in as part of opts:

var Widget = Backbone.Model.extend({

    widgetCount: 0,

    defaults: {
        id: null,
        name: null
    }

    initialize: function(attr, opts) {
       // attr contains the "fields" set on the model
       // opts contains anything passed in after attr
       // so we can do things like this
       if( opts && opts.widgetCount ) {
          this.widgetCount = opts.widgetCount;
       }
    }
});

var widget = new Widget({name: 'the blue one'}, {widgetCount: 20});

Keep in mind that if you declare objects or arrays on the class, they are essentially constants and changing them will modify all instances:

var Widget = Backbone.Model.extend({

    someOpts: { one: 1, two: 2},

    initialize: function(attr, opts) {
       // this is probably not going to do what you want because it will
       // modify `someOpts` for all Widget instances.
       this.someOpts.one = opts.one; 
    }
});

Upvotes: 3

Related Questions