0

私のバックボーン アプリでは、特定のクラス (から拡張されたもの) のすべての子クラスのリストが必要ですA。これを達成するために、デフォルトのメソッドをオーバーライドしたいのですがextend、私の(おそらく素朴な)アプローチは機能しません。

var A = Backbone.Model.extend({
  /* ... */
}, {
  __children: [],
  extend: function () {
    var Klass = this;
    result = Klass.__super__.extend.apply(Klass, arguments);
    Klass.__children.push(result);
    return result;
  }
});
B = A.extend({}, {className: "B"});
A.__children // === []

なぜこれが機能しないのですか?extend メソッドをオーバーライドする際に何か魔法があるのでしょうか?

4

1 に答える 1

0

拡張メソッドが特別であることがわかりました。ご覧のとおり

> Backbone.Model.extend
function (protoProps, classProps) {
    var child = inherits(this, protoProps, classProps);
    child.extend = this.extend;
    return child;
  }

extendメソッドは、何をしようとしても、親クラスのメソッドで上書きされます。したがって、これを回避する方法は、extend メソッドを後で「修正」することです。

var enableChildTracking = function (Klass) {
    var old_extend = Klass.extend;
    Klass.__children = [];
    Klass.extend = function () {
        var That = this;
        var result = old_extend.apply(That, arguments);
        That.__children.push(result);
        result.__children = [];
        return result;
    };
};

var A = Backbone.Model.extend({});
enableChildTracking(A);

B = A.extend({}, {className: "B"});
C = A.extend({}, {className: "C"});
A.__children.map(function (child) {return child.className}); /* == ["B", "C"] */

もちろん、この方法で Backbone.Model の拡張を直接オーバーライドしたり、拡張の場合にイベントを送信したり、コールバック (Ruby 風) を呼び出したりすることもできます。

于 2012-09-10T17:20:25.897 に答える