2012-01-06 5 views
5
私は自分Backbone.Viewをサブクラス化しています

。スーパークラスでは、場合関数を初期化し、私が書く:はなぜBackbone.View.constructorです.__ super__未定義私は_.bindAll(これ)を使用する場合

_.bindAll(この、 '多くの'、 'メソッド');スーパークラスでは、私が使用している場合、

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

:しかし

そして、私は、このコンテキストにバインドする方法を指定して、私は経由して、サブクラスからスーパー呼び出すことができます

_.bindAll(this) 
私は、私のサブクラスからスーパーを呼び出すために行くとき

ではなく、

this.constructor.__super__ 

は未定義です。なぜそれが知恵ですか?

+0

ないあなたが指摘しようとしているのかわからは、私はそれのためにjsfiddleを出し始めていますが、アンダースコアのbindメソッドを使用してactuallの問題でそれを完了だろうか? http://jsfiddle.net/saelfaer/7fCbT/ – Sander

答えて

3

単にスーパー呼び出すためにこれを使用しない理由:

は(私は明確化のために複数の行に分離しています、あなたは1行で通話を行うことができます)

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

Reference: GetPrototypeOf

1

I getConstructor()を使用してパッチバックしたバックボーン。コンストラクタを返し、_.bindAllの影響を受けません。

使用法:

this.getConstructor().__super__; 

が実装のみ:この問題に対する解決策ではなく、説明がありますよう

(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

を見て、私は1つを供給しようとするつもりだ...

下線のbindAll方法は、単一の引数(オブジェクト)と呼び出されたとき、そのオブジェクトのすべての関数タイプのプロパティは、もはや元の関数を参照していないが、代わりにコンテキストを修正する別のもの

オブジェクトタイプの関数の1つは、です。このオブジェクトは、バックボーンコンストラクタ関数(プロパティ__super__)を参照するため、新しい関数で上書きされます。そして、これはobject.constructorはもはや財産__super__を持っていないことを意味します。私は、アンダースコアの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; 
} 

それは、アンダースコアのバージョンとほとんど同じだが_.extend()を使用して新しい機能に元の関数のいずれかのプロパティが追加されます。

0

私はバックボーンへの新たなんだが、また、あなたが拡張メソッドにメソッドを含むオブジェクトを渡すことを期待他のフレームワークと4年以上の経験を持っていますが、問題はこれが作用するのに十分なきめ細かな制御を与えるものではありませんです渡されるオブジェクト内に含まれるメソッド。

さらに多くのコントロールを得るには、クロージャを渡して継承し、クロージャがオブジェクトを返すことができます。この手法は、一般に、きめ細かな制御と洗練された可能性を提供し、特定の問題を解決するために活用することができます。例えば

  1. バックボーン固有、:メソッドを返すクロージャ内部

    、これらの方法は、2つの広いカテゴリーに分けることができます私たちは自分の別のオブジェクトから私たちのアプリケーションに固有のカスタムメソッドを返す場合は、アプリケーションに固有の

  2. カスタム、

を初期化し、私たちはその後、_.bindAllの「部分適用」を_.bind使用することができます&コンストラクタそれらのカスタムメソッド名に変換します。その後、一緒にすべてを置く

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() {}, 
     } 
    } 
}());