2011-03-07 4 views
4

J'essaie d'appliquer les propriétés d'objet de objA à objB mais j'ai réalisé Ext.apply est imparfait (ou béni?) D'une manière où il s'applique uniquement les objets de premier niveau ensemble.Existe-t-il une meilleure façon d'utiliser Ext.apply pour combiner des enfants/sous-objets dans un autre objet?

Exemple:

var objA = { 
    name: 'objA', 
    baseParams: { 
     cols: [1,2,3,4,5] 
    } 
}; 

//used in subclass 
var objB = { 
    name: 'objB', 
    baseParams: { 
     limit: 50, 
     sort: 'name' 
    } 
}; 

//used in baseclass 
var objC = { 
    name: 'objC', 
    baseParams: { 
     as_hash: true, 
     limit: 20 
    } 
}; 

Ext.apply(objB,objA); //used in subclass 
Ext.apply(objC,objB); //used in baseclass 

Exemple de sortie sera:

obj = { 
    name: 'objA', 
    baseParams: { 
     cols: [1,2,3,4,5] 
    } 
}; 

Je voudrais cette sortie à la place (sortie attendue):

obj = { 
    name: 'objA', 
    baseParams: { 
     cols: [1,2,3,4,5], 
     as_hash: true, 
     limit: 50, 
     sort: 'name' 
    } 
}; 

Comment puis-je parvenir sans faire ce?

// subclass: 
var bpTemp = {}; 
bpTemp.baseParams = Ext.apply(objB.baseParams, objA.baseParams); 
Ext.apply(objB,objA); 
Ext.apply(objB,bpTemp); 

// base class: 
var bpTemp = {}; 
bpTemp.baseParams = Ext.apply(objC.baseParams, objB.baseParams); 
Ext.apply(objC,objB); 
Ext.apply(objC,bpTemp); 
+0

, attendons avec impatience une bonne solution – ChrisR

+0

Merci, toujours à la recherche d'une réponse si. – CincauHangus

Répondre

1

Vous pouvez changer la voie Ext.apply() fonctionne de telle sorte qu'un 4ème argument peut être booléen impliquant « profond » apply - cela fonctionnera avec votre exemple (par défaut profondes à true): question intéressante

Ext.apply = function(o, c, defaults, deep){ 
    deep = deep!==false; 
    // no "this" reference for friendly out of scope calls 
    if(defaults){ 
     Ext.apply(o, defaults); 
    } 
    if(o && c && typeof c == 'object'){ 
     for(var p in c){ 
      o[p] = (deep && Ext.isObject(o[p]) && Ext.isObject(c[p])) ? Ext.apply(o[p], c[p]) : c[p]; 
     } 
    } 
    return o; 
}; 
+0

FYI - J'ai par défaut l'argument "deep" à true pour que votre exemple fonctionne ... mais je ne ferais pas cela dans votre application parce que Ext peut dépendre de non-deep s'applique en interne - je le ferais explicitement "profond" au cas par cas dans votre application –

+1

vous avez une bonne solution, mais ce n'est pas pratique ni conseillé de changer une fonction de bibliothèque car cela peut affecter les autres personnes qui l'utilisent (surtout si c'est une méthode couramment utilisée). Je marque cela comme une réponse parce qu'elle répond à la question. – CincauHangus

+0

D'accord, mais ce changement pourrait être sûr (r) si vous avez par défaut "profond" à faux ... –

0

Vous pouvez essayer une solution récursive, avec quelques cas particuliers, comme ci-dessous:

function deepApply(receiver, config, defaults) { 
    if (defaults) { 
     deepApply(receiver, defaults); 
    } 
    if (receiver && config && typeof config == 'object') { 
     for (var p in config) { 
      if (typeof config[p] != 'object' || Ext.isArray(config[p])) { 
       receiver[p] = config[p]; 
      } else { 
       if (typeof receiver[p] != 'object') { 
        receiver[p] = {}; 
       } 
       deepApply(receiver[p], config[p]); 
      } 
     } 
    } 
    return receiver; 
} 
Questions connexes