通过路径

时间:2017-09-12 17:24:50

标签: javascript knockout.js lodash

我有一个可以有任意数量级别的对象,并且可以拥有任何现有属性。此外,可以观察到对象和/或其属性。 例如:

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

我需要有一种方法来设置任何嵌套级别的所有属性(可观察的和不可观察的),其方式如下:

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

我尝试使用lodash函数_.set(),它仅在属性不是可观察的情况下有效,但obj中的属性(我必须更新)可以是 - 可观察的或不可观察的。 我很感激任何帮助,谢谢。

2 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:0)

yoel neuman,谢谢你的回答,这对我帮助很大。我把你的函数作为基本方法进行了小修正:

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

不幸的是,我没有足够的声誉来投票给你答案。非常感谢你的帮助!