将嵌套对象中的值与相应的敲除绑定匹配?

时间:2014-09-18 19:33:12

标签: javascript object knockout.js

假设我有一个放置在嵌套/命名空间对象中的敲除绑定列表,类似于:

var bindings = {
    event: {
        eventid: ko.observable(),
        office: ko.observable(),

        employee: {
            name: ko.observable(),
            group: ko.observable()
        }
    },
    ...
}

现在假设有许多不同的数据集可以加载到这个中 - 所以我们会执行ajax查询并获得这样的JSON结果:

{
    "defaults": {
        "event": {
            "eventid": 1234,

            "employee": {
                "name": "John Smith"
            }
        },
        ...
    }
}

请注意,并非每个绑定都有默认值 - 但所有默认值都映射到绑定。我想要做的是将默认值读入它们对应的任何敲除绑定。

肯定有traverse a nested object的方法并阅读其价值观。在该示例中添加一个额外的参数,我可以跟踪默认的完整密钥(例如event.employee.name)。我感到难过的地方是取default的密钥并使用它来定位相关的淘汰赛绑定。显然,即使我有key = "event.employee.name"bindings.key也没有引用我想要的内容。我只能想到使用eval(),这让我的口味不好。

如何使用密钥引用不同对象中的相同位置?也许淘汰提供了一种将对象自动映射到其绑定的方法,我只是忽略了它?任何见解都会有所帮助。提前谢谢!

2 个答案:

答案 0 :(得分:2)

我建议您查看Knockout Mapping Plugin,它将完成您想要做的大部分工作。如果这不是锻炼,那么您可以将bindings对象转换为一系列接受数据参数的构造函数。类似

var Employee = function (data){
	var self = this;
  	self.name = ko.observbale(data.name || '');
  	self.group = ko.observable(data.group);
};

var Event = function(data){
	var self = this;
  	self.eventid = ko.observable(data.id || 0);
  	self.office = ko.observable(data.office || '');
  	self.employee = ko.observable(new Employee(data.employee));
};


var bindings = function(data){
    var self = this;
  	self.event = ko.observable(new Event(data));
}

答案 1 :(得分:0)

我将把Nathan Fisher的解决方案纳入未来的更新,但我想分享我现在找到的解决方案。每次defaults对象递归时,我只需传递相应的绑定对象,而不是跟踪整个关键路径。

var setToDefaults = function(data){
    loopDefaults(data.defaults, bindings);
};

var loopDefaults = function(defaults, targ){
    for(var d in defaults){
        if(defaults.hasOwnProperty(d) && defaults[d]!==null){
            if(typeof(defaults[d])=="object"){
                loopDefaults(defaults[d], targ[d]);
            }else{
                // defaults[d] is a value - set to corresponding knockout binding
                targ[d](defaults[d]);
            }
        }
    }
};