2012-01-06 13 views
5

Podklasy moje własne Backbone.View. Jeśli w funkcji "inicjowania" super klasy napiszę:Dlaczego mój Backbone.View.constructor .__ super__ undefined, jeśli używam _.bindAll (this)

_.bindAll (this, 'many', 'methods');

i określić metody, które chcę wiązać się z tym kontekście mogę zadzwonić Super z podklasy poprzez:

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

Ale jeśli w super klasy, używam:

_.bindAll(this) 

zamiast tego, gdy idę na wywołanie super z moim podklasy,

this.constructor.__super__ 

jest niezdefiniowany. Każda mądrość, dlaczego tak się dzieje?

+0

nie wiem, co starasz się podkreślić, zacząłem się jsfiddle dla niego, ale można go wypełnić swój Actuall problemów z metody wiązania podkreślenia jest? http://jsfiddle.net/saelfaer/7fCbT/ – Sander

Odpowiedz

3

Dlaczego po prostu nie korzystać z tego nazwać super:

(jestem oddzielając do kilku linii dla wyjaśnienia, można wykonać połączenie w jednej linii)

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

Reference: GetPrototypeOf

1

I poprawiony Backbone z getConstructor(), który zwraca konstruktor i jest odporny na _.bindAll.

Zastosowanie:

this.getConstructor().__super__; 

Realizacja:

(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

Widząc, jak nie tylko rozwiązania tego problemu, ale nie wyjaśnienia, będę próbować dostarczyć jedną ...

Gdy metoda Underscore na bindAll jest wywoływana za pomocą pojedynczego argumentu (obiektu), wszystkie właściwości typu funkcji tego obiektu nie odwołują się już do pierwotnej funkcji, ale zamiast tego inny, który poprawia kontekst.

Ponieważ jedną z właściwości obiektu funkcji typu jest constructor, która jest odniesieniem do funkcji Konstruktora szkieletu (z właściwością __super__), właściwość zostanie zastąpiona nową funkcją. Oznacza to, że object.constructor nie będzie już mieć właściwości __super__.

Aby obejść ten problem kiedyś następującą funkcję jako alternatywa dla podkreślenia jest bindAll:

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; 
} 

To prawie identyczna do wersji podkreślenia, ale dodaje żadnych właściwości pierwotnej funkcji do nowych funkcji poprzez zastosowanie _.extend() .

0

Jestem nowicjuszem w Backbone, ale mam ponad 4 lata doświadczenia w innej strukturze, która oczekuje również, że przekażesz obiekt zawierający metody do metody rozszerzającej, ale problem polega na tym, że nie daje to dostatecznie drobiazgowej kontroli do działania metody zawarte w przekazywanym obiekcie.

Aby uzyskać większą kontrolę, można zamiast tego przekazać zamknięcie, aby przedłużyć, a zamknięcie może zwrócić obiekt. Technika ta w ogólności pozwala na dokładniejszą kontrolę i większą możliwość wyrafinowania i może być wykorzystana do rozwiązania konkretnego problemu.

Wewnątrz zamknięcie, które powraca do metod, metody te mogą być podzielone na dwie główne kategorie:

  1. trzon specyficzne np konstruktor & zainicjować
  2. Niestandardowa, specyficzne dla danej aplikacji

Jeśli wrócimy metody niestandardowe specyficzne dla naszej aplikacji z własnej oddzielny obiekt, możemy użyć _.bind dla „częściowego zastosowania” z _.bindAll tylko te niestandardowe nazwy metod.

Składając to wszystko razem, to:

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() {}, 
     } 
    } 
}()); 
Powiązane problemy