web-dev-qa-db-ja.com

Backbone.jsでのモデルスーパークラスのデフォルトの拡張

this への質問としてこれを提起したいと思いますが、そうすることはできません。お詫び申し上げます。

サブクラスのデフォルトを拡張すると、スーパークラスに反映されます。これは目的に反するようで、私が探している構造を取得するために、サブクラスのスーパークラスのデフォルトを明示的にリストする傾向があります。

var Inventory = Backbone.Model.extend({
    defaults: {
        cat: 3,
        dog: 5
    }
});

var ExtendedInventory = Inventory.extend({
});

_.extend(ExtendedInventory.prototype.defaults, {rabbit: 25});

var i = new Inventory();
var ei = new ExtendedInventory();
console.log(i.attributes);
console.log(ei.attributes);

これは出力します:

{cat: 3, dog: 5, rabbit: 25}
{cat: 3, dog: 5, rabbit: 25}

op )が私が望んでいるものではない:

{cat: 3, dog: 5}
{cat: 3, dog: 5, rabbit: 25}
37
mcdoh

問題はそれです Inventory.prototype.defaultsおよびExtended.prototype.defaultsは参照をオーバーライドしていないため、同じ参照を持っています。

だからあなたは2つの方法でこれを行うことができます、多分もっとですが私はこれを見つけました:

編集:最初の例は正しくありません(コメントを参照)。 2番目を参照してください。

var ExtendedInventory = Inventory.extend({
    defaults: {
        rabit:25
    }
});

_.extend(ExtendedInventory.prototype.defaults, Inventory.prototype.defaults);

または

var ExtendedInventory = Inventory.extend({
    defaults: _.extend({},Inventory.prototype.defaults,
         {rabit:25}
    )
});

最初はきれいに見えます。

50
JCorcuera

私はそれを解決する最良の方法は、underscore.jsの_.defaultsメソッドを使用することだと思います。これにより、Modelサブクラスのデフォルト値をオーバーライドできます。

_.defaults(ExtendedInventory.prototype.defaults, 
           Inventory.prototype.defaults);

次の例をご覧ください。

http://jsfiddle.net/mattfreer/xLK5D/

18
b73

JCorcueraの回答の拡張として、基本クラスがデフォルトを定義する関数を使用する(または使用する可能性がある)場合、これはうまく機能します。

_   defaults: function() {                                     
     return _.extend( _.result(Slot.prototype, 'defaults'),{  
       kind_id: 6,                                  
       otherthing: 'yello'  
       // add in your extended defaults here                                
   })}                                                      
_

子のデフォルトメソッドおよび_.result()での関数の使用である重要なビット docs

3
ErichBSchulz

さらに別の方法は、アンダースコアの_.extendこれを実現する関数:

var SuperClass = Backbone.Model.extend({
  baseDefaults: {
    baseProp1: val,
    baseProp2: val2
  }
});

var SubClass = SuperClass.extend({
  defaults: _.extend({
    prop1: val,
    prop2: val2
  }, SuperClass.prototype.baseDefaults)
})
0
dipole_moment

ExtendedInventory.defaultsにrabbitを追加した結果、Inventory.prototype.defaultsが変更されないことを確認したいのはあなたの言うとおりです。私の原始的な継承は、以下がなぜ機能するのかを明確に説明するには不十分ですが、これはあなたが望んでいることを実行すると思います。

ExtendedInventory.defaults = {}
_.extend(ExtendedInventory.defaults, ExtendedInventory.prototype.defaults, {rabbit: 25});

_.extendメソッドについて覚えておくべき重要な点は、最初の引数がdestinationであることです。最初の引数の後の引数からすべての属性を取得し、それらを宛先引数に配置します。

別のポイントは、ExtendedInventory.prototype.defaults === Inventory.prototype.defaultsがtrueになるということです。つまり、それらは同じオブジェクトであるため、ExtendedInventoryのプロトタイプを変更すると、Inventoryのプロトタイプが変更されます(理由はわかりません)そもそも同等です)。

0
c3rin

Underscore.jsは値を深く拡張しないと思います。配列がある場合は、Jquery $ .extendを使用する必要があります。試すことができます ここ

var basemodel = Backbone.Model.extend({
  defaults:{a:{"1":"1","2":4,"4":5},b:2}
}
);

var model1 = basemodel.extend({
    defaults: $.extend(false,basemodel.prototype.defaults,{a:{"1":1,"2":2},b:{"xx":13}})
});


var model2 = basemodel.extend({
    defaults: $.extend(false,basemodel.prototype.defaults,{a:{"1":1,"2":2},z:13})
});



var m1 = new model1();
var m2 = new model2();


alert(JSON.stringify(m1.toJSON()));
alert(JSON.stringify(m2.toJSON()));

また、作業を正しく行うには、最初のパラメーターに「false」を指定する必要があります。それが本当であるとき、ただお互いを交錯させてください。

0
sanji_san
var MoveToolModel = ToolModel.extend({
    extendDefaults: {
        cursor: 'move'
    },
    initialize: function() {
        ToolModel.prototype.initialize.apply(this, arguments);
        this.defaults = _.extend({}, this.defaults, this.extendDefaults);
    },
    draw: function(canvasContext, data) {
        //drag
    }
});
0
Oleksandr Knyga