我有一个带有嵌套属性的复杂对象,它从null变为实际填充的对象。我可以通过ko.mapping.fromJSON第一次将所有内容映射得很好。但是当一个事件导致后续映射发生时,属性变为null而其他事件获得值,映射变得疯狂:
当“更新!”时单击按钮,警报('1')将触发,并显示“Test2”。但是,请单击“更新!”再次和警报('2')发射,但文本不会改变。有什么想法吗?
HTML:
<p> <span>Name:</span>
<span data-bind="text: IntroData ? IntroData.Name : TempData.Name"></span>
<button id="update" data-bind="click: Update">Update!</button>
</p>
javascript:
var ViewModel = function (data) {
var me = this;
ko.mapping.fromJS(data, {}, me);
me.Update = function () {
if (me.Index() == '0' || me.Index() == '2') {
alert('1');
ko.mapping.fromJS(stuff2, {}, me);
} else {
alert('2');
ko.mapping.fromJS(stuff3, {}, me);
}
};
return me;
};
var stuff = {
Index: '0',
IntroData: {
Name: 'Test'
},
TempData: null
};
var stuff2 = {
Index: '1',
IntroData: {
Name: 'Test2'
},
TempData: {
Name: 'Temp2'
}
};
var stuff3 = {
Index: '2',
IntroData: null,
TempData: {
Name: 'Temp3'
}
};
window.viewModel = ko.mapping.fromJS(new ViewModel(stuff));
ko.applyBindings(window.viewModel);
答案 0 :(得分:0)
你在东西和东西中为IntroData和TempData提供了不同的形状。
1 /当ko.mapping.fromJS解释TempData:null时,它将产生一个ko.observable(null)。 2 /当ko.mapping.fromJS解释TempData:{Name:'Temp3'}时,它将生成一个具有成员'Name'的Object,它是一个ko.observable('Temp3')。
例如,东西:
> ko.mapping.fromJS({ Index: '0', IntroData: { Name: 'Test' }, TempData: null }, {});
Object {Index: function, IntroData: Object, TempData: function, __ko_mapping__: Object}
Index: function observable() {
IntroData: Object
Name: function observable() {
__proto__: Object
TempData: function observable() {
__ko_mapping__: Object
__proto__: Object
and stuff2:
> ko.mapping.fromJS({ Index: '1', IntroData: { Name: 'Test2' }, TempData: { Name: 'Temp2' } }, {});
Object {Index: function, IntroData: Object, TempData: Object, __ko_mapping__: Object}
Index: function observable() {
IntroData: Object
Name: function observable() {
__proto__: Object
TempData: Object
Name: function observable() {
__proto__: Object
__ko_mapping__: Object
__proto__: Object
请注意,TempData是stuff的映射对象中的一个函数(可观察),但是在stuff2的映射对象中具有子属性“Name”的对象。
那为什么这不起作用?您的绑定指定:
text: IntroData ? IntroData.Name : TempData.Name
问题是IntroData 永远不为空,并且始终是“真实的”。 (它可以是一个对象,也可以是一个可观察的。在任何一种情况下,都不是null。)那么该怎么办?好吧,我们可以使定义形状相似,以便ko.mapping正确更新值。我将你的绑定修改为:
text: IntroData.Name() ? IntroData.Name : TempData.Name
并将您的对象定义更改为:
var stuff = {
Index: '0',
IntroData: {
Name: 'Test'
},
TempData: {
Name: null
}
};
var stuff2 = {
Index: '1',
IntroData: {
Name: 'Test2'
},
TempData: {
Name: 'Temp2'
}
};
var stuff3 = {
Index: '2',
IntroData: {
Name: null
},
TempData: {
Name: 'Temp3'
}
};
您会看到更新按钮现在显示每次点击的更改。看起来你正试图循环使用东西 - &gt; stuff2 - &gt; stuff3。代码不会这样做,但你不应该发现很难做到这一点。 : - )