What's the best way to override Model.get(attr) in Backbone.js?

前端 未结 3 1167
野趣味
野趣味 2020-12-24 02:37

I\'m using Backbone.js for the first time, and liking it so far. One thing I can\'t work out at the moment in dynamic attributes of models. For example, say I have a Person

相关标签:
3条回答
  • 2020-12-24 03:08

    I would think of attributes as the raw materials used by a model to provide answers to callers that ask the questions. I actually don't like having callers know too much about the internal attribute structure. Its an implementation detail. What if this structure changes?

    So my answer would be: don't do it.

    Create a method as you've done and hide the implementation details. Its much cleaner code and survives implementation changes.

    0 讨论(0)
  • 2020-12-24 03:16

    Would this be simpler?

    var Person = Backbone.Model.extend({
      get: function (attr) {
        if (typeof this[attr] == 'function')
        {
          return this[attr]();
        }
    
        return Backbone.Model.prototype.get.call(this, attr);
      }
    });
    

    This way you could also override existing attributes with functions. What do you think?

    0 讨论(0)
  • 2020-12-24 03:22

    The actual properties used by Model.get are stored in the attribute property. You could do something like this:

    // function to cross-browser add a property to an object
    function addProperty(object, label, getter, setter) {
        if (object.defineProperty){
          object.defineProperty(object, label, {getter: getter, setter: setter})
        }
        else {
            object.__defineGetter__(label, getter)
            object.__defineSetter__(label, setter)
        }
    }
    
    // inside the initializer of your model, add a property to the attribute object
    var Person = Backbone.Model.extend({
        initialize: function(attr, options) {
            var t = this;
            ...
            addProperty(this.attributes, 'fullName',
                function() {return t.get('firstName') + ' ' + t.get('surname'),     
                function(val) {...}
            )
        }  
    })
    

    This will allow you to do person.get('fullName') as you requested.

    Edit: To be clear, I agree with Bill's answer below. Shouldn't really be dinking around with the internal implementation of backbone.js. Especially since this is incomplete...what about escape() instead of get()? And the setter is more complex, as it does validation, change notification, etc...now I'm sorry I posted this :)

    0 讨论(0)
提交回复
热议问题