我认为您问题的解决方案来自以错误的方式思考视图模型。视图模型不仅是向视图传递数据的东西,而且还是用于提交数据的占位符。
我通常最终使用淘汰赛的方式,我永远不会最终将空视图模型发送到视图。视图模型通常具有我绑定的所有字段。虽然它们可能是空字符串,或者没有显示值的初始化对象,但实际对象仍然存在,每个对象都正确表示为我绑定到的字段。
您可能想研究简单地向视图发送空对象而不是什么。
编辑:这个例子是联合国 ASP.NET MVC
所以基本上,我在服务器端创建了一个视图模型对象,其中包含所有需要显示的数据以及所有需要收集的数据。为了更容易验证代码,我通常将要收集的数据放入它自己的子类中,但这完全取决于您的代码需求。
在任何情况下,进入视图的任何对象都继承自 vmBase 类,该类基本上提供了一个 toJSON() 方法,该方法生成对象的 JSON 序列化。这在我的视图中被视图引擎调用。如下面的代码所示。
<script type='text/javascript'>
var viewModel = ko.mapping.fromJS(<%= Model.ToJson() %>);
$(document).ready( function () {
ko.applyBindings(viewModel);
});
</script>
当我准备好重新发送代码时,我只需删除视图模型的 JS 版本。
<script type='text/javascript'>
var dataToSendToServer = ko.toJS(viewModel);
</script>
在一些 sanarios 中,只有一部分视图模型在发生变化(如果您正在进行 AJAX 更新),您可以做一些很酷的事情,例如切换模板以便可以应用不同的绑定。在这种情况下,我们使用#ID_of_Container作为原始数据/模板的容器,并将模板(可以包含 data-bind="" 元素)替换为新模板ID_of_Template
<script type='text/javascript'>
ko.cleanNode($("#ID_of_Container"));
delete (viewModel.Some_Element_To_Be_Updated);
viewModel = ko.mapping.updateFromJS(viewModel, New_Data_For_That_Element);
// Use ko.toJS(viewModel) because standard template plugin doesn't understand
// knockout observables
$("#ID_of_Container").html($("#ID_of_Template").tmpl(ko.toJS(viewModel)))
ko.applyBindings(viewModel, $("#ID_of_Container")[0]);
</script>