Razor 数据绑定MVC-4到Knockout.js foreach

Razor 数据绑定MVC-4到Knockout.js foreach,razor,knockout.js,asp.net-mvc-4,Razor,Knockout.js,Asp.net Mvc 4,我们的web应用程序中有一个表单,它在一个地方要求用户输入一个值列表。我们使用Razor和knockout.js编写了表单的这一部分,因此列表的每个值都有一个文本框,类似于。我们如何将这些文本框数据绑定到MVC模型 这是我们的表格: @model OurProject.Models.Input.InputModel @{ ViewBag.Title = "Input"; } <h2> Inputs</h2> <div id="inputKOApp"&

我们的web应用程序中有一个表单,它在一个地方要求用户输入一个值列表。我们使用Razor和knockout.js编写了表单的这一部分,因此列表的每个值都有一个文本框,类似于。我们如何将这些文本框数据绑定到MVC模型

这是我们的表格:

@model OurProject.Models.Input.InputModel
@{
    ViewBag.Title = "Input";
}
<h2>
    Inputs</h2>
<div id="inputKOApp">
    @using (Html.BeginForm())
    {
        <!-- snip - lots of part of our form that work correctly -->
        <div class="row-fluid">
            <div class="control-group">
                <div class="span8 control-label">
                    @Html.LabelFor(model => model.POSTransactionCodes)
                </div>
                <div class="controls">
                    <!-- These are the textboxes we would like to bind to MVC -->
                    <ul class="pull-right" data-bind="foreach: POSTransactionCodes">
                        <li>
                            <input data-bind="value: code" />
                            <a href="#" data-bind="click: $root.removePOSTransactionCode">Delete</a></li>
                    </ul>
                    <button class="pull-right" data-bind="click: addPOSTransactionCode">
                        Add another POS Transaction Code</button>
                    @Html.ValidationMessageFor(model => model.POSTransactionCodes, null, new { @class = "help-inline" })
                </div>
            </div>
        </div>
        <!-- snip - more cshtml that is irrelevant to the problem -->
</div>
        <input type="submit" value="Submit" />
    }
</div>
<script type="text/javascript" src='~/Scripts/jquery-1.8.2.min.js'></script>
<script type="text/javascript" src='~/Scripts/knockout-2.1.0.js'></script>
<script type="text/javascript" src='~/Scripts/OP/OP.js'></script>
<script type="text/javascript" src='~/Scripts/OP/Input/OP.Input.Input.Form.js'></script>
<script type="text/javascript" src='~/Scripts/OP/Input/OP.Input.Input.Data.js'></script>
<script type="text/javascript">
    var inputApp = $('#inputKOApp')[0];
    OP.Input.Form.init(inputApp);
</script>
以下是我们的MVC模型:

namespace OurProject.Models.Input
{
    public class InputModel : IModel
    {
        //Snip - lots of properties that aren't interesting for this problem
        [Required]
        [DisplayName("POS Transaction Codes")]
        public List<double> POSTransactionCodes { get; set; }

        public InputModel()
        { }

        /* I ommitted a few other methods that
         * aren't relevant to this problem. */
    }
}
名称空间OurProject.Models.Input
{
公共类输入模型:IModel
{
//Snip-许多属性对此问题不感兴趣
[必需]
[显示名称(“POS交易代码”)]
公共列表转换后代码{get;set;}
公共输入模型()
{ }
/*我推荐了一些其他的方法
*与此问题无关*/
}
}

我不知道如何将数据发送回服务器,但您需要以允许模型绑定的方式命名输入:

如果要绑定到列表/集合,则输入的名称应如下所示:

<input type="text" name="CollectionPropertyName[index]" />

多亏了内梅斯夫的回答,让我了解一下这一点

但是我需要有用于jquery验证的“普通”名称和id属性。因此,我想到了编写自己的数据绑定器的想法

ko.bindingHandlers.nameId = {
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor(),
            allBindings = allBindingsAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);
        var bindName = $(element).data('bind-name');
        bindName = bindName.replace('{0}', valueUnwrapped);
        $(element).attr({name : bindName, id : bindName});
    }
};
并在html中使用它

<input
      data-bind="value: qty, nameId: $index"
      data-bind-name="inventory[{0}].qty" />

{
   //...
   POSTransactionCodes: [ 1 , 3  ]
   //..
}
ko.bindingHandlers.nameId = {
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor(),
            allBindings = allBindingsAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);
        var bindName = $(element).data('bind-name');
        bindName = bindName.replace('{0}', valueUnwrapped);
        $(element).attr({name : bindName, id : bindName});
    }
};
<input
      data-bind="value: qty, nameId: $index"
      data-bind-name="inventory[{0}].qty" />