knockout.js选择元素绑定在后续表单提交时丢失值

时间:2013-03-20 14:08:50

标签: forms select knockout.js viewmodel element

我有一个淘汰视图模型从JSON调用填充。 在表单中的select元素中,我有一组选项(也来自viewmodel)和值observableArray的一部分。 问题仅在于select元素而不是输入元素 - 在提交表单时,只有在select中分配的值包含正确的值。因此,从JSON成功加载并以形式呈现但保持不变的那些将作为options数组中的第一个值发送回服务器。

HTML表单:

<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,它是viewmodels 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元素。当select保持不变(未重新选择)时,viewmodel将其值作为选项(InvoiceTypes)数组中的第一项,当发布到服务器时。 最后,我可能会忘记一些微不足道的事情,这是我第一次更严重的淘汰赛.js尝试。

注意:InvoiceTypeScaledCostEntries的一部分,即observableArrayInvoiceTypesobservableArrayInvoiceTypesScaledCostEntries都来自JSON,ScaledCostEntries会被发回。

1 个答案:

答案 0 :(得分:3)

我的假设是,这是由于表单提交时服务器上ScaledCostEntries的处理方式。

我遇到问题之前(跨越各种服务器端框架)我有一个主要模型,其中包含正在添加和删除的依赖模型列表,并且表单提交是针对要更新的主模型完成的一切。

问题在于,在表单提交期间,当请求中的值被映射到服务器端模型时,空白值表示“无变化”而不是“删除此”。这适用于直接在模型上的属性,但不适用于依赖模型的列表。

我发现有两种处理方法:使用Ajax删除底层模型,并在视图中按下“删除”或“删除”按钮时更新与主模型的关系;或者每次都明确地发送整个模型列表,并为每个表单提交明确地删除和重建服务器上的列表。每种方法都适用于不同的情况,也可能有其他方法可以很好地运作。