Estendendo le impostazioni predefinite di un Modello superclasse in Backbone.js

Vorrei porre questa come una questione di questo risposta, ma non riesco a farlo, mi scuso.

Estendere le impostazioni predefinite per la sottoclasse si riflettono nella superclasse. Questo sembra sconfiggere lo scopo e io sono più propenso ad elencare esplicitamente la superclasse ” defaults nella sottoclasse di recuperare la struttura che sto cercando.

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

Questo output:

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

Non è quello che voglio (né, suppongo, la op) vuoi:

{cat: 3, dog: 5}
{cat: 3, dog: 5, rabbit: 25}
InformationsquelleAutor mcdoh | 2011-07-01

 

7 Replies
  1. 50

    Il problema è che Inventory.prototype.defaults e Extended.prototype.defaults ha lo stesso riferimento, perché non ignorare il riferimento.

    Così si può fare in 2 modi, o forse più, ma ho trovato solo questo 2:

    Edit: Il primo esempio non è corretto (vedi commenti); si prega di fare riferimento alla seconda.

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

    o

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

    Penso che il primo sembra più pulito.

    • Grazie, @JCorcuera. Mi hanno guardato più attentamente _.extend() per capire questo. Un problema con questa soluzione, però, è che se io cambio il ExtendedInventory default {dog: 15, rabbit: 25} ExtendedInventory del valore di dog viene sovrascritto torna a 5. Credo che tornerò a for (a in this.eiDefaults) {this.attributes[a] = this.eiDefaults[a];} in ExtendedInventory del initialize metodo.
    • mm hai ragione, ma il secondo funziona bene.
    • Sei corretto, così sembra che la tua seconda soluzione è il modo per andare su questo. Grazie per il vostro aiuto!
  2. 18

    Penso che il modo migliore per risolverlo è quello di utilizzare underscore.js’s _.impostazioni predefinite di metodo. Questo vi permetterà di sostituire i valori predefiniti nel Modello sottoclasse:

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

    Vedi questo esempio:

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

  3. 3

    Come un’estensione di JCorcuera la risposta, se la classe base utilizza o potrà utilizzare una funzione di definire i valori predefiniti, quindi questo funziona bene:

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

    il tasto po ‘ essere l’uso di un funciton nel bambino default del metodo e _.result() docs

  4. 0

    Penso che tu abbia ragione che si desidera assicurarsi che l’Inventario.prototipo.default non cambia l’aggiunta di coniglio al ExtendedInventory.le impostazioni predefinite. Il mio protoypical eredità non è sufficiente per spiegare chiaramente perché i seguenti lavori, ma credo che questo faccia quello che si vuole fare.

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

    Un punto importante da ricordare a proposito l’ _.estendere il metodo è che il primo argomento è destination. Prende tutti gli attributi che gli argomenti che dopo il primo argomento e li inserisce l’argomento di destinazione.

    Un altro punto è che ExtendedInventory.prototipo.defaults === Inventario.prototipo.impostazioni predefinite risultati in vero, nel senso che sono lo stesso oggetto, quindi se si cambia il prototipo di ExtendedInventory si modifica il prototipo di Inventario (non sono sicuro del perché sono uguali anche se in primo luogo).

  5. 0
    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
        }
    });
  6. 0

    Penso underscore.js non estendere valori profondamente. Si dovrebbe usare Jquery $.estendere se si dispone di un array. Si può provare qui

    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()));

    Inoltre, si dovrebbe dare il primo parametro “false” per fare il vostro lavoro correttamente. quando è vero, basta intrecciano a vicenda.

  7. 0

    Ancora un altro modo per utilizzare il carattere di sottolineatura del _.extend funzione per eseguire questa operazione:

    var SuperClass = Backbone.Model.extend({
      baseDefaults: {
        baseProp1: val,
        baseProp2: val2
      }
    });
    
    var SubClass = SuperClass.extend({
      defaults: _.extend({
        prop1: val,
        prop2: val2
      }, SuperClass.prototype.baseDefaults)
    })

Lascia un commento