2017-09-12 3 views
0

J'ai un objet qui pourrait avoir n'importe quel nombre de niveaux et pourrait avoir des propriétés existantes. De plus, l'objet et/ou ses propriétés peuvent être observables. Par exemple:Définir la propriété observable de l'objet par le chemin

var obj = { 
    prop: "qqq", 
    obsProp: ko.observable({ 
     nestedObsProp: ko.observable({ 
     prop: 'value' 
     }) 
    }) 
}; 

je dois avoir un moyen de définir toutes les propriétés (à la fois observables et non observables) de tous les niveaux imbriqués dans une façon quelque chose comme ceci:

set(obj, 'obsProp.nestedObsProp.prop', 'new value'); 

J'ai essayé de utiliser la fonction lodash _.set(), cela ne fonctionne que si les propriétés ne sont pas observables, mais les propriétés dans obj (que je dois mettre à jour) peuvent être à la fois - observables ou non. J'apprécierais toute aide, merci.

Répondre

0
function set (source, key, newValue) { 
    const hierarchy = key.split('.'); 
    const property = hierarchy.pop(); 

    const retrived = hierarchy.reduce((source, key) => { 
     return source[key]; 
    }, source) || source; 

    if (ko.isObservable(retrived[property])) { 
     retrived[property](newValue); 
    } else { 
     retrived[property] = newValue; 
    } 
} 
0

yoel neuman, merci pour votre réponse, cela m'a beaucoup aidé. J'ai pris votre fonction comme approche de base avec de petites corrections:

function set(source, path, newValue) { 
    const hierarchy = path.split('.'); 
    const property = hierarchy.pop(); 

    var retrieved = hierarchy.reduce((source, key) => { 
     return ko.isObservable(source) ? source()[key] : source[key]; 
    }, source) || source; 

    retrieved = ko.isObservable(retrieved) ? retrieved() : retrieved; 
    if (ko.isObservable(retrieved[property])) { 
     retrieved[property](newValue); 
    } else { 
     retrieved[property] = newValue; 
    } 
} 

Malheureusement, je n'ai pas assez de réputation pour voter pour votre réponse. Beaucoup apprécié votre aide!