2014-01-11 66 views
1

使用ko.mapping.fromJSON只要定义了嵌套对象,我就可以从JSON进行绑定。当我将嵌套对象更新为空或空时,绑定就会中断。Knockout映射嵌套对象绑定在null时不更新

在此代码中,我有五个不同的数据集,我使用model.nextDataset函数进行迭代。当数据集到达第四个和第五个变体时,它将中断与内部对象的绑定。

var datasets = ["{\"id\": 1,\"reference\": \"reference1\",\"inner\": {\"id\": 1,\"name\": \"name1\"}}", 
    "{\"id\": 1,\"reference\": \"reference2\",\"inner\": {\"id\": 1,\"name\": \"name2\"}}", 
    "{\"id\": 1,\"reference\": \"reference3\",\"inner\": {\"id\": null,\"name\": null}}", 
    "{\"id\": 1,\"reference\": \"reference3\",\"inner\": {}}", 
    "{\"id\": 1,\"reference\": \"reference3\",\"inner\": null}"]; 

var mapping = { 
    'create': function (options) { 
     return new Model(options.data); 
    }, 
     'key': function (data) { 
     return ko.utils.unwrapObservable(data.id); 
    }, 
     'inner': { 
     'create': function (options) { 
      return new InnerModel(options.data); 
     } 
    }, 
     'key': function (data) { 
     return ko.utils.unwrapObservable(data.id); 
    } 
}; 
/* 
var innerMapping = { 
    'key': function(data) { 
     return ko.utils.unwrapObservable(data.id); 
    } 
}; 
*/ 
var InnerModel = function (data) { 
    var self = this; 
    ko.mapping.fromJS(data, {}, self); 
    self.innerName = ko.computed(function() { 
     return self.name() + " computed"; 
    }, self); 
}; 

var Model = function (data) { 
    var self = this; 
    ko.mapping.fromJS(data, mapping, self); 
    self.innerName = ko.computed(function() { 
     return self.inner.name() + " computed"; 
    }, self); 
} 

var model = { 
    dataset: ko.observable(0), 
    model: ko.mapping.fromJSON(datasets[0], mapping, model), 
    nextDataset: function() { 
     model.dataset(model.dataset() + 1); 
     if (datasets.length === model.dataset()) { 
      model.dataset(0); 
     } 
     ko.mapping.fromJSON(datasets[model.dataset()], mapping, model.model); 
    } 
} 

ko.applyBindings(model); 

伴随HTML:

<div id="testko"> 
    <p>Dataset: <span data-bind="text: dataset"></span><p> 
    <input type="text" data-bind="value: model.reference" /><br> 
    <div data-bind="with: model.inner"><input type="text" data-bind="value: innerName" /><br></div> 
    <input type="text" data-bind="value: model.innerName" /><br> 
    <input type="button" data-bind="click: nextDataset" value="Next Dataset" /> 
</div> 

我已经做了的jsfiddle,试图证明这一点:

http://jsfiddle.net/Ku4KN/

我相信,我错误地以某种方式映射,但我避风港” t已经足够长的时间来使用淘汰赛来说明原因。

+0

您正在访问inner.name,但inner为空! – LostInComputer

回答

0

由于计算的observable正在访问self.name(),其中self被设置为null - 这是mapping插件的正常行为,并且正确使用with binding可以阻止大多数人运行的问题在这种情况下。映射插件无法为空对象创建对象结构。

问题是,您在内核名计算的observable中得到一个javascript错误,因此knockout库不会继续运行 - 只需在self.name()周围添加一个空检查,就像您基本上使用“与“绑定”。