2012-01-06 10 views
5

Estoy subclasificando mi propio Backbone.View. Si, en la función de inicialización de la clase superior, escribo:¿Por qué mi Backbone.View.constructor .__ super__ undefined si uso _.bindAll (this)

_.bindTodos (esto, 'muchos', 'métodos');

y especificar los métodos que quiero que se unen a este contexto, puedo llamar súper de la subclase a través de:

this.constructor.__super__.initialize.apply(this, arguments); 

Pero, si en la superclase, que utilizo:

_.bindAll(this) 

lugar, cuando voy a llamar súper de mi subclase,

this.constructor.__super__ 

no está definido. ¿Alguna sabiduría sobre por qué es eso?

+0

no está seguro de lo que estás tratando de señalar, empecé a cabo una jsFiddle para ello, pero se puede completar con sus problemas actuallos con método de enlace del guión? http://jsfiddle.net/saelfaer/7fCbT/ – Sander

Respuesta

3

Por qué no simplemente usar esto para llamar a la súper:

(I estoy separando a varias líneas de aclaración, se puede hacer la llamada en una línea)

var thisProto = Object.getPrototypeOf(thisInstance); 
var superProto = Object.getPrototypeOf(thisProto); 
superProto.superMethod.apply(thisInstance, [param1, param2]); 

Reference: GetPrototypeOf

1

I Backbone parcheado con getConstructor(), que devuelve el constructor y es inmune a _.bindAll.

Uso:

this.getConstructor().__super__; 

Implementación:

(function() { 
    var backboneExtend = Backbone.Model.extend; 
    var constructorExtend = function() { 
    var child = backboneExtend.apply(this, arguments); 
    child.prototype.getConstructor = function() { 
     return child; 
    }; 
    return child; 
    }; 
    Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = constructorExtend; 
})(); 
2

En vista de que sólo hay soluciones a este problema, pero no explicaciones, voy a tratar de suministrar una ...

Cuando se invoca el método bindAll de Underscore con el único argumento (el objeto), todas las propiedades del tipo de función de ese objeto ya no hacen referencia a la función original, sino que otro que arregla el contexto.

Dado que una de las propiedades del objeto de la función de tipo es constructor, que es una referencia a la función del constructor Backbone (con la propiedad __super__), la propiedad se sobrescribirá con una nueva función. Esto significa que object.constructor ya no tendrá una propiedad __super__.

Para solucionar este problema que utiliza la siguiente función como una alternativa a bindAll de Subrayado:

function safeBindAll(obj) { 
    var funcs = Array.prototype.slice.call(arguments, 1); 

    if (funcs.length == 0) { 
     funcs = _.functions(obj); 
    } 

    _.each(funcs, function(f) { 
     var oldProps = obj[f]; 
     obj[f] = _.bind(obj[f], obj); 

     _.extend(obj[f], oldProps); 
    }); 

    return obj; 
} 

Es casi idéntica a la versión de Subrayado pero añade propiedades de la función original para la nueva función a través del uso de _.extend() .

0

Soy nuevo en Backbone pero tengo más de 4 años de experiencia con otro framework que también espera pasar un objeto que contenga métodos a un método extendido, pero el problema es que esto no le da un control lo suficientemente preciso como para actuar sobre los métodos contenidos dentro del objeto que se pasa.

Para obtener más control, puede pasar un cierre para ampliar, y el cierre puede devolver un objeto. Esta técnica en general permite un control más detallado y más potencial para la sofisticación, y puede aprovecharse para resolver su problema específico.

En el interior del cierre que devuelve los métodos, dichos métodos se pueden dividir en dos amplias categorías:

  1. -Backbone específico, por ejemplo constructor & inicializar
  2. personalizada, específica de su aplicación

Si volvemos los métodos personalizados específicos para nuestra aplicación de su propio objeto separado, que se puede utilizar para _.bind "aplicación parcial" de _.bindAll a solo esos nombres de métodos personalizados.

Poniendo todo junto a continuación:

var foobar = Backbone.Model.extend(function() { 
    var foobarMethods = modelMethods(); 

    return _.extend({}, foobarMethods, { 
     constructor: function() { 
      _.bind(_.bindAll, this, _.keys(foobarMethods)); 
      // equivalent to _.bindAll(this, 'foo', 'bar') except that the above 
      // allow methods to be arbitrarily added or removed 
     }, 
     initialize : function() {}   
    }); 

    //It's possible to "mixin" these methods from another file 
    function modelMethods() { 
     return { 
      foo: function() {}, 
      bar: function() {}, 
     } 
    } 
}()); 
Cuestiones relacionadas