¿Cuál es la mejor manera de anular Model.get (attr) en Backbone.js?

Estoy usando Backbone.js por primera vez, y me gusta hasta ahora. Una cosa que no puedo resolver en este momento es la de los attributes dynamics de los models. Por ejemplo, supongamos que tengo un model de persona y quiero get su nombre completo:

var Person = Backbone.Model.extend({ getFullName: function () { return this.get('firstName') + ' ' + this.get('surname'); } }); 

Entonces podría hacer person.getFullName() . Pero me gustaría mantenerlo consistente con los otros getters, más como person.get('fullName') . No veo cómo hacer eso sin anular desorderadamente Person # get. ¿O es esa mi única opción?

Esto es lo que tengo hasta ahora para la opción principal:

 var Person = Backbone.Model.extend({ get: function (attr) { switch (attr) { case 'fullName': return this.get('firstName') + ' ' + this.get('surname'); break; case 'somethingElse': return this.doSomethingClever(); break; default: return Backbone.Model.prototype.get.call(this, attr); } } }); 

Supongo que no es terrible, pero parece que debería haber una mejor manera.

¿Sería esto más simple?

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

De esta forma, también podría anular los attributes existentes con funciones. ¿Qué piensas?

Me gustaría pensar en los attributes como las materias primas utilizadas por un model para proporcionar respuestas a las personas que llaman que hacen las preguntas. De hecho, no me gusta que las personas que llaman saben demasiado sobre la estructura interna de los attributes. Es un detalle de implementación. ¿Qué pasa si esta estructura cambia?

Entonces mi respuesta sería: no lo hagas.

Cree un método como lo ha hecho y oculte los detalles de la implementación. Es un código mucho más limpio y sobrevive a los cambios de implementación.

Las properties reales utilizadas por Model.get se almacenan en la propiedad del atributo. Podrías hacer algo como esto:

 // 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) {...} ) } }) 

Esto le permitirá hacer person.get ('fullName') como lo solicitó.

Editar: Para ser claros, estoy de acuerdo con la respuesta de Bill a continuación. Realmente no debería estar dando vueltas con la implementación interna de backbone.js. Sobre todo porque esto está incompleto … ¿qué pasa con escape () en lugar de get ()? Y el setter es más complejo, ya que valida, cambia notifications, etc. … ahora lamento haber publicado esto 🙂