如何从与ASP.NET MVC中的控制器的模型数据绑定的表中以编程方式添加/删除行

时间:2019-04-25 15:03:44

标签: c# asp.net-mvc asp.net-mvc-5

我有一个Asp.NET MVC页面,其模型类似于

namespace Sample.Models
{
    public class ContModel
    {
        [Display(Name = "Name")]
        public string Name { get; set; }

        [Display(Name = "Code")]
        public string Code { get; set; }

        [Display(Name = "Customer")]
        public string Customer { get; set; }

        public List<Order> Orders { get; set;}
    }

    public class Order
    {
        public string OrderId;
        public string OrderDesc;
    }
}

我已使用本文成功绑定了模型数据 https://www.pluralsight.com/guides/asp.net-mvc-getting-default-data-binding-right-for-hierarchical-views

本文给出的示例使用 for循环并@Html.TextBoxFor组成表格。现在,我要以编程方式添加\删除行。

到目前为止,我提到的所有示例都使用jQuery插入行。并且所有表行均以JSON字符串形式形成,并使用AJAX调用传递给控制器​​。

AJAX是这样做的唯一方法吗?是否有适当的方法来绑定新添加的行的数据,以便它们将自动使用POST传递给表单提交?

2 个答案:

答案 0 :(得分:0)

好,首先,免责声明:我尚未测试以下代码,它可能有些不完整,可能无法立即使用。但是,我认为所有主要概念都可以用一点点应用的思想带给您想要去的地方。

此外,我也不完全确定如果在模型绑定期间绑定到列表的项目的索引值不按顺序排列或丢失(例如,如果您有3个订单的列表并删除了一个带有索引2的行,您将拥有一个绑定了索引1和3的列表,它如何创建缺少2的列表-您必须自己检查一下。)

如果您对其进行测试,发现有问题,那么您可能必须重新考虑我快速尝试存储计数器变量并在删除行时重新索引现有html中各项的名称的尝试。 -如果您在JavaScript中使用了全局变量,则可以完全取消计数器变量,这将在整个页面的生命周期中保持其值,但是已经有一段时间了,因为我已经做了类似的事情,而我似乎记住它的工作方式,我不能肯定地说。

删除: 删除后,您需要了解如何删除什么。有两种方法可以很快想到;

  1. 一旦在控制器中建立了模型,就可以检入数据库,哪些在数据库中,哪些不在列表中,然后从数据库中删除列表中缺少的那些

  2. 删除项目后,您将OrderId存储在另一个以逗号分隔的字符串(如“ 3,25,100”)中的隐藏输入中,并且也将其绑定到模型。这样,当您将模型放入控制器中时,只需在逗号上分割,然后遍历数组并删除相应的顺序即可。

我敢肯定,还有很多其他方法可以做到这一点。

<table>
    <thead>
        <tr>
            <th></th>
            <th>Description</th>
            <th><button id="AddOrder">Add Order></button></th>
        </tr>
    </thead>
    <tbody id="tableBody">
@for (int i = 0; i < Model.Orders.Count(); i++)
{
    var item = Model.Orders[i];

        <tr id="Order-@item.OrderId">
            <td>
                <button type="button" data-id="@item.OrderId" class="removeOrderBtn"></button>
                @* The trick to model binding with a list is the name attribute matching the Property Name on the model and giving it an index as below *@
                <input type="hidden" name="Orders[@i].OrderId" value="@item.OrderId" />
            </td>
            <td>
                @item.OrderDesc
                <input type="hidden" name="Orders[@i].OrderDesc" value="@item.OrderDesc" id="OrderDesc-@item.OrderId" />
            </td>
        </tr>

}
    </tbody>
</table>
@*Store the value of the last index in this input to keep track of it constantly*@ 
<input type="hidden" id="count" value="@(Model.Orders.Count()-1)">


<script type="text/javascript">

    $("#AddOrder").on('click', function (e) {

        //get the counter input and store it because we're going to update the value later.
        var counterInput = $("#count");
        var counter = counterInput.val();
        counter++;
        //Assumed your new order description has an id of description.
        var description = $("#description").val();
        //Again you need to prepare your html so that the model binding will work by forming the name correctly.
        var newRow = "<tr><td><input type='hidden' name='Orders[" + counter + "].OrderId' value='0' /></td><td <input type='hidden' name='Orders[" + counter + "].OrderDesc value=" + description +" /></td></tr>";
        var tableBody = $("#tableBody");
        //Append the new tr to the table body after the other rows (might be a better way to do this with append or something similar).
        tableBody[0].innerHTML = tableBody[0].innerHTML + newRow;

        //Update the counter stored in the input so that we can keep track of how many items we have in the list to try avoid duplicate numbers
        counterInput.val(counter);
    });

    $(".removeOrderBtn").on('click', function (e) {
        var id = e.target.dataset.id;

        var tableBody = $("#tableBody");
        tableBody.remove("#Order-" + id); // I think this takes a selector.
        var counterInput = $("#count");
        var counter = counterInput.val();
        counter--;
        counterInput.val(counter);

    });

</script>

如果您有任何疑问,请告诉我。

答案 1 :(得分:0)

尝试这个,希望对您有用

<script src="//jsfiddle.net/mustafaozkaya/nfxz4ep2/18/embed/"></script>