javascript backbone.js prototypal-inheritance

javascript - Extendiendo los valores predeterminados de una superclase de modelo en Backbone.js



prototypal-inheritance (7)

Me gustaría plantear esto como una pregunta a this respuesta, pero parece que no puedo hacerlo, me disculpo.

La extensión de los valores predeterminados para la subclase se refleja en la superclase. Esto parece frustrar el propósito y estoy más dispuesto a enumerar explícitamente los valores predeterminados de la superclase en la subclase para obtener la estructura que estoy buscando.

var Inventory = Backbone.Model.extend({ defaults: { cat: 3, dog: 5 } }); var ExtendedInventory = Inventory.extend({ }); _.extend(ExtendedInventory.prototype.defaults, {rabbit: 25}); var i = new Inventory(); var ei = new ExtendedInventory(); console.log(i.attributes); console.log(ei.attributes);

Esto produce:

{cat: 3, dog: 5, rabbit: 25} {cat: 3, dog: 5, rabbit: 25}

No es lo que yo (ni, supongo, el op ) quiero:

{cat: 3, dog: 5} {cat: 3, dog: 5, rabbit: 25}


Como una extensión de la respuesta de JCorcuera, si su clase base usa (o puede usar) una función para definir los valores predeterminados, esto funcionará muy bien:

defaults: function() { return _.extend( _.result(Slot.prototype, ''defaults''),{ kind_id: 6, otherthing: ''yello'' // add in your extended defaults here })}

la clave es el uso de un funciton en el método _.result() y _.result() docs


Creo que la mejor manera de resolverlo es usar el método _defaults_ de underscore.js. Esto le permitirá anular los valores predeterminados en su subclase de Modelo:

_.defaults(ExtendedInventory.prototype.defaults, Inventory.prototype.defaults);

Mira este ejemplo:

http://jsfiddle.net/mattfreer/xLK5D/


Creo que tiene razón en que desea asegurarse de que Inventory.prototype.defaults no cambie como resultado de agregar rabbit a ExtendedInventory.defaults. Mi herencia protoípica no es lo suficientemente buena como para explicar claramente por qué funciona lo siguiente, pero creo que hace lo que usted quiere que haga.

ExtendedInventory.defaults = {} _.extend(ExtendedInventory.defaults, ExtendedInventory.prototype.defaults, {rabbit: 25});

Un punto importante para recordar sobre el método _.extend es que el primer argumento es el destination . Toma todos los atributos de los argumentos después del primer argumento y los coloca en el argumento de destino.

Otro punto es que ExtendedInventory.prototype.defaults === Inventory.prototype.defaults da como resultado verdadero, lo que significa que son el mismo objeto, por lo que si cambias el prototipo de ExtendedInventory cambias el prototipo de Inventory (no estoy seguro de por qué son iguales, en primer lugar).


Creo que underscore.js no amplía los valores profundamente. Debería usar Jquery $ .extend si tiene alguna matriz. Puedes intentarlo here

var basemodel = Backbone.Model.extend({ defaults:{a:{"1":"1","2":4,"4":5},b:2} } ); var model1 = basemodel.extend({ defaults: $.extend(false,basemodel.prototype.defaults,{a:{"1":1,"2":2},b:{"xx":13}}) }); var model2 = basemodel.extend({ defaults: $.extend(false,basemodel.prototype.defaults,{a:{"1":1,"2":2},z:13}) }); var m1 = new model1(); var m2 = new model2(); alert(JSON.stringify(m1.toJSON())); alert(JSON.stringify(m2.toJSON()));

También debe darle al primer parámetro "falso" para que haga su trabajo correctamente. cuando es verdad, simplemente entrelazan entre sí.


El problema es que Inventory.prototype.defaults y Extended.prototype.defaults tienen la misma referencia, porque no ha anulado la referencia.

Entonces puedes hacer esto de 2 maneras, tal vez más, pero solo encontré este 2:

Editar: el primer ejemplo es incorrecto (ver comentarios); por favor refiérase al segundo.

var ExtendedInventory = Inventory.extend({ defaults: { rabit:25 } }); _.extend(ExtendedInventory.prototype.defaults, Inventory.prototype.defaults);

o

var ExtendedInventory = Inventory.extend({ defaults: _.extend({},Inventory.prototype.defaults, {rabit:25} ) });

Creo que el primero se ve más limpio.


Otra forma es usar la función _.extend del _.extend para lograr esto:

var SuperClass = Backbone.Model.extend({ baseDefaults: { baseProp1: val, baseProp2: val2 } }); var SubClass = SuperClass.extend({ defaults: _.extend({ prop1: val, prop2: val2 }, SuperClass.prototype.baseDefaults) })


var MoveToolModel = ToolModel.extend({ extendDefaults: { cursor: ''move'' }, initialize: function() { ToolModel.prototype.initialize.apply(this, arguments); this.defaults = _.extend({}, this.defaults, this.extendDefaults); }, draw: function(canvasContext, data) { //drag } });