underscore source examples backbonejs backbone annotated javascript backbone.js

javascript - source - underscore js download



Backbone.js constructor personalizado? (6)

Algo que debe tener en cuenta al anular el constructor Backbone.Model: si no llama a Backbone.Model.apply , es posible que Model.cid no esté configurado.

Eso es malo: si cid no está configurado en varios modelos, la colección puede considerar que es un duplicado del primer modelo de su colección y no permitirá que se agregue.

Estoy buscando algunos ejemplos para crear un constructor personalizado en mis modelos. Quiero que la estructura del modelo / los datos de manera diferente a continuación, simplemente configurándolo como atributos.

¿Alguien me puede mostrar algún ejemplo básico de cómo hacer esto?

¡Gracias!


Así es como anulo el constructor Backbone.Model predeterminado:

Backbone.Model = (function(Model) { // Define the new constructor Backbone.Model = function(attributes, options) { // Your constructor logic here // ... // Call the default constructor if you wish Model.apply(this, arguments); // Add some callbacks this.on(''event'', this.myCallback, this); }; // Clone static properties _.extend(Backbone.Model, Model); // Clone prototype Backbone.Model.prototype = (function(Prototype) { Prototype.prototype = Model.prototype; return new Prototype; })(function() {}); // Update constructor in prototype Backbone.Model.prototype.constructor = Backbone.Model; return Backbone.Model; })(Backbone.Model);

Después de eso, debe asegurarse de que el prototipo Backbone.Collection use el constructor Backbone.Model actualizado:

_.extend(Backbone.Collection.prototype, { model: Backbone.Model });

La "ventaja" de este enfoque, en mi opinión, es que puede seguir usando Backbone.Model como su constructor de modelos, lo que hace que el cambio sea más transparente.


Como mencioné en el comentario, tenga cuidado al usar this.constructor.__super__ (o this.__super__ ), para que no termine en un bucle sin fin (el Maximum call stack size exceeded en Chrome).

Intente lo siguiente en la consola (bajo su propio riesgo, llevará al bucle sin fin mencionado anteriormente)

var A = Backbone.Model.extend({constructor: function () { console.log("log: A"); this.constructor.__super__.constructor.apply(this, arguments); }}); var B = A.extend({constructor: function () { console.log("log: B"); this.constructor.__super__.constructor.apply(this, arguments); }}); new A(); // log: A // > Backbone.model.extend.constructor new B(); // log: B // (8192) log: A // > RangeError: Maximum call stack size exceeded

La razón es que al crear B , this en el constructor para A apunta a una instancia de B , por lo que este this.constructor.__super__.constructor sigue apuntando hacia el constructor de A , que se llama repetidamente.

Si desea "comportamiento deseado", use una de las siguientes sintaxis:

var A = Backbone.Model.extend({constructor: function () { console.log("log: A"); A.__super__.constructor.apply(this, arguments); }}); var B = A.extend({constructor: function () { console.log("log: B"); B.__super__.constructor.apply(this, arguments); }}); new A(); // log: A // > Backbone.model.extend.constructor new B(); // log: B // log: A // > A.extend.constructor

o directamente sin __super__ :

var A = Backbone.Model.extend({constructor: function () { console.log("log: A"); Backbone.Model.apply(this, arguments); }}); var B = A.extend({constructor: function () { console.log("log: B"); A.apply(this, arguments); }}); new A(); // log: A // > Backbone.model.extend.constructor new B(); // log: B // log: A // > A.extend.constructor


Parece que estás buscando el método de initialize . Se llama cuando crea un nuevo modelo, y puede usarlo para lo que necesite para:

var myModel = Backbone.Model.extend({ initialize: function() { // do something besides setting attributes or model alert(''myModel is ready for action!''); } }); new myModel();

Si está buscando hacer algo más complicado, puede anular el método del constructor en el núcleo de Backbone. Aunque es un asunto mucho más complicado. Mucho mejor trabajar con métodos expuestos si puedes!


Si quieres escribir tu modelo por ti mismo, así:

var YourModel = function () { // your constructor here }; _.extend(YourModel.prototype, Backbone.Model.prototype, { // your model method here });

Tenga cuidado, creo que necesita consultar el código fuente del constructor Backbone.Model . Pero creo que esta no es una buena idea. Anular el método de initialize es la forma correcta

var YourModel = Backbone.Model.extend({ initialize: function (attrs, options) { Backbone.Model.prototype.initialize.apply(this, arguments); // call super constructor // your constructor code here } });


Si realmente desea anular el constructor, pase una propiedad del constructor a Backbone.Model.extend() , por ejemplo:

var Klass = Backbone.Model.extend( { constructor : function ( attributes, options ) { // ... } } );

Si desea llamar al constructor incorporado desde su constructor personalizado, puede hacer algo como:

var Klass = Backbone.Model.extend( { constructor : function ( attributes, options ) { Backbone.Model.apply( this, arguments ); } } );

O si no quiere tener que repetir el nombre de la variable que contiene la clase primaria en toda la subclase, o no quiere preocuparse por el cambio del valor de esa variable, puede hacer algo como lo siguiente:

var Klass; var parent_klass = Backbone.Model.prototype; ( function ( parent_klass ) { Klass = parent_klass.constructor.extend( { constructor : function ( attributes, options ) { parent_klass.constructor.apply( this, arguments ); } } ); } )( parent_klass );

O si prefiere la forma en que lo sugiere @Claude , pero repita el nombre de la variable de subclase dentro de la subclase en lugar del nombre var de la clase principal:

var Klass = Backbone.Model.extend( { constructor : function ( attributes, options ) { Klass.parent_klass.constructor.apply( this, arguments ); } }, { parent_klass : Backbone.Model.prototype } );

Si desea más consejos que eso, tendrá que ser más específico sobre lo que quiere lograr.

Cualquier cosa que solo quieras hacer después de la funcionalidad incorporada del constructor, probablemente deberías hacerlo en initialize() .