How to get backbone model attributes without .get

39,421

Solution 1

Model attributes that you use get() and set() or defaults to get/set are stored in the instance.attributes attribute.

Also, these are the attributes that are going to be passed to and returned from sync() as well as toJSON(). So when you fetch(), save() etc, only what is stored in instance.attributes gets passed along.

Nothing will stop you of course from having normal attributes like instance.foo on your objects. If you want to treat those as the other attributes and pass these along to fetch() and save() you can do so by providing a custom parse() on your model which by default does nothing. That said, you should only do this if you really deem it absolutely necessary, if only to comply to the Backbone conventions.

Solution 2

The attributes are accessible at Model.attributes. You can read directly from that, but use set to change them. You can also get a representation of all your attributes from Model.toJSON() (note: toJSON() doesn't actually return JSON, but a javascript object).

The recommended way is to use toJSON() for templates, serialization etc.

Solution 3

There isn't away around this, really. You could use model.attributes.att_name, but that's probably not what you want.

JavaScript doesn't have (at least not in all browsers) the ability to redirect access of properties.

Share:
39,421
Adam Fraser
Author by

Adam Fraser

Hi, I'm Adam. I design and develop things that people use.

Updated on March 09, 2020

Comments

  • Adam Fraser
    Adam Fraser about 4 years

    In backbone it seems that I have to get model attributes via model.get('att_name')

    I'd prever to get them the way I'd get any public field within an object: model.att_name

    Can anyone think of a way to get around this?

    eg: In python world I would override getattr on the model something like this:

    def getattr(self, att):
       return self.get(att)
    

    Oh, and I'm using CoffeeScript

  • Adam Fraser
    Adam Fraser about 12 years
    What if I did something like this in initialize: for att in @attributes: @[att] = ()->@get(att) ?
  • ggozad
    ggozad about 12 years
    Sorry, but I don't speak coffescript. I guess that means this[attr] = this.get(attr). That will not intercept any further attribute manipulation through sync, set. Additionally it will only give you getters, but not setters.
  • Adam Fraser
    Adam Fraser about 12 years
    Ah sorry, equiv is this: this[att] = function(){this.get(att)} ...so I could do model.get('att') via model.att() ...not ideal, but I'm hoping you can tell me whether this will break any of Backbone's functionality. And thanks btw.
  • ggozad
    ggozad about 12 years
    Sure this will work. As a getter of course not as a setter, and you will still miss whatever attributes are not yet set. I would still avoid it, not because it violates something, but because it won't work with say attributes that are not set in init.
  • Adam Fraser
    Adam Fraser about 12 years
    Understood. Looks like toJSON is probably my best option for getting the syntax I want in my templates then. Thanks again for your help.
  • troelskn
    troelskn about 11 years
    You could do this[att] = function(val) { return typeof(val) == "undefined" ? this.get(att) : this.set(att, val); }. Still would only work when a model has been retrieved from a backend (E.g. a new model won't have any initial attributes, so won't work). There's probably some performance overhead as well.