我有一个从JSON调用填充的knockout视图模型。在表单中的选择元素中,我有一组选项(也来自viewmodel)和值,observableArray
的一部分。问题只与select元素有关,而与输入元素无关——在提交表单时,只有在select中分配的值包含正确的值。因此,那些已经成功地从JSON中加载并以表单形式呈现,但保持不变的,将作为选项数组中的第一个值发送回服务器。
<form>
<table >
<thead>
...
</thead>
<tbody data-bind='foreach: ScaledCostEntries'>
<tr>
<td><input data-bind='value: StartDateString' class="startdate" type="text"/></td>
<td><select data-bind='value: InvoiceType, options: $root.InvoiceTypes'></select></td>
<td><a href='#' data-bind='click: $root.removeCost'>Delete</a></td>
</tr>
</tbody>
</table>
<button data-bind='click: addCost'>Add New Row</button>
<button data-bind='click: save' >Update</button>
</form>
在上面的代码中,问题是InvoiceType,视图模型ScaledCostEntries
observableArray的一部分。(另外,如果我交换值和选项的顺序,那将不会在select元素中放置选定的值)。
和JS:
<script type="text/javascript">
$(function () {
var scaledCostModel = function () {
var self = this;
self.ScaledCostEntries = ko.observableArray([]);
self.InvoiceTypes = ko.observableArray([]);
self.addCost = function () {
self.ScaledCostEntries.push({
StartDateString: ko.observable(),
InvoiceType: ko.observable()
});
};
self.removeCost = function (cost) {
cost.IsDeleted = true;
self.ScaledCostEntries.destroy(cost);
};
self.save = function (form) {
jQuery.ajax({
url: '@Request.Url.PathAndQuery',
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: ko.toJSON(self.ScaledCostEntries)
});
};
};
jQuery.getJSON('@Request.Url.PathAndQuery', function (data) {
ko.mapping.fromJS(data, {}, viewModel);
});
var viewModel = new scaledCostModel();
ko.applyBindings(viewModel);
});
</script>
所以,总结一下,问题是viewmodel的属性绑定到一个select元素。当选择保持不变(不重新选择),视图模型将有它的值从选项(InvoiceTypes
)数组的第一项,当张贴到服务器。最后,我可能忘记了一些琐碎的事情,这是我第一次更认真的knockout.js尝试。
注:InvoiceType
是ScaledCostEntries
的一部分,即observableArray
。InvoiceTypes
是observableArray
。InvoiceTypes
和ScaledCostEntries
都来自JSON, ScaledCostEntries
被发送回来。
我的假设是,这是由于如何在服务器上处理ScaledCostEntries
表单提交。
我以前遇到过这个问题(跨各种服务器端框架),当我有一个主模型,其中有一个正在添加和删除的依赖模型列表,并且对主模型进行表单提交以更新所有内容。
问题是,在表单提交期间,当请求中的值被映射到服务器端模型时,空白值被认为是"无更改",而不是"删除此"。这可以很好地处理模型上的属性,但不适用于依赖模型的列表。
我发现有几种方法可以处理这个问题:使用Ajax删除底层模型,并在视图中按下"删除"或"删除"按钮时更新与主模型的关系;或者每次显式地发送整个模型列表,并为每次表单提交显式地删除和重建服务器上的列表。每种方法都适用于不同的情况,可能还有其他方法也可以很好地工作。