当使用分页时,使用DataTable在MVC中提交带有实体的模型失败

本文关键字:提交 实体 失败 模型 MVC 分页 DataTable 使用 | 更新日期: 2023-09-27 18:15:19

我想提交模型与实体,但控制器是不接收实体切换到另一个页面时使用DataTable插件

视图:

using (Ajax.BeginForm("EditLeads", new { mode = Model.leadMode }, new AjaxOptions {     OnBegin = "displayAllDataTable", UpdateTargetId = "leadDisplay", LoadingElementId =     "spinner", OnSuccess = "refreshLeadsAfterRemovingAndTabSwitching" }, new  {     id="dataTableForm"}))
{ 
<table id="dataTable">
    <thead>
        <tr>
            <th style="max-width: 40px;">
                Select
            </th>
            <th>
                Date added
            </th>
            <th>
                Contact name
            </th>
            <th>
                Contact number
            </th>
            <th>
                Email
            </th>
            <th>
                Source
            </th>
            <th>
                Status
            </th>
            <th>
                Assigned to user:
            </th>
            <th>
                Back up user:
            </th>
            <th>
                Comments
            </th>
        </tr>
    </thead>
    <tbody>
        @for (int i = 0; i < Model.leadsList.Count; i++)
        {
            <tr>
                <td style="width: 40px; vertical-align: middle; text-align: center">
                <span class="hideDisplayField">@Model.leadsList[i].leadId</span>
                @Html.HiddenFor(model => model.organisationId)
                 @Html.HiddenFor(model => Model.leadsList[i].leadId)
                    @Html.CheckBoxFor(model => Model.leadsList[i].selected, new { @class = "selectedLead", data_val = false, data_leadId = Model.leadsList[i].leadId, id = "selected_" + Model.leadsList[i].leadId })
                </td>
               @* <td>
                    @Html.DisplayFor(model => model.leadsList[i].leadId)
                    @Html.HiddenFor(model => Model.leadsList[i].leadId)
                </td>*@
                <td>
                    <span class="hideDisplayField">@Model.leadsList[i].leadDate</span>
                    @Html.DisplayFor(model => Model.leadsList[i].leadDate)
                </td>
                @*  <td>
                    @Html.HiddenFor(model => Model.leadsList[i].leadId)
                    <span class="hideDisplayField">@Model.leadsList[i].description</span>
                    @Html.EditorFor(model => Model.leadsList[i].description)
                </td>*@
                <td>
                    <span class="hideDisplayField">@Model.leadsList[i].contactName</span>
                    @Html.DisplayFor(model => Model.leadsList[i].contactName)
                </td>
                <td>
                    <span class="hideDisplayField">@Model.leadsList[i].contactMobile</span>
                    @Html.EditorFor(model => Model.leadsList[i].contactMobile)
                </td>
                <td>
                    <span class="hideDisplayField">@Model.leadsList[i].contactEmail</span>
                    @Html.EditorFor(model => Model.leadsList[i].contactEmail)
                    @Html.HiddenFor(model => Model.leadsList[i].contactId)
                </td>
                <td>
                </td>
                <td>
                    <span class="hideDisplayField">@Model.leadsList[i].leadStatusName</span>
                    @Html.DropDownListFor(model => Model.leadsList[i].leadStatusId, new SelectList(Model.leadStatusList, "leadStatusId", "name", Model.leadsList[i].leadStatusId), null, new { data_val = false })
                </td>
                <td>
                    <span class="hideDisplayField">@Model.leadsList[i].assignedToUserId</span>
                    @Html.DropDownListFor(model => Model.leadsList[i].assignedToUserId, new SelectList(Model.users, "UserId", "Email", Model.leadsList[i].assignedToUserId), "Select user", new { data_val = false, data_users = Model.leadsList[i].leadId, @class = "usersList" })
                </td>
                <td>
                    <span class="hideDisplayField">@Model.leadsList[i].backupUserId</span>
                    @Html.DropDownListFor(model => Model.leadsList[i].backupUserId, new SelectList(Model.users, "UserId", "Email", Model.leadsList[i].backupUserId), "Select user", new { data_val = false })
                </td>
                <td>
                </td>
            </tr>
        }
    </tbody>
    <tfoot>
        <tr>
            <th>
                Select
            </th>
            <th>
                Date added
            </th>
            <th>
                Contact name
            </th>
            <th>
                Contact mobile
            </th>
            <th>
                Email
            </th>
            <th>
                Source
            </th>
            <th>
                Status
            </th>
            <th>
                Assigned to user
            </th>
            <th>
                Back up user
            </th>
            <th>
                Comments
            </th>
        </tr>
    </tfoot>
</table>
<div id="assignUserToLeads">
    <h4>
        Assign selected to</h4>
    @Html.DropDownList("userList", new SelectList(Model.users, "UserId", "Email"), "Select user")
</div>
<input type="submit" value="Save" />
}

我的控制器期望接收模型与线索列表。

public ActionResult EditLeads(LeadsVM leadVM, string mode, FormCollection form)
    {
        // Assign user to lead
        var user = form["userList"];
        var leadsToUpdate = leadVM.leadsList.Where(m => m.selected == true);
        foreach (var lead in leadsToUpdate) ...

如果我从下拉列表中选择值在页面上显示100个项目,一切工作正常,但是一旦我切换到另一个页面,名称绑定正在崩溃,模型正在为leadVM.leadsList传递null。我做了个小hack,我觉得可能会有帮助。在模型被发送到控制器之前,我调用displayAllDataTable函数。

function displayAllDataTable() {
        console.log($("#dataTable_length select"));
        $("#dataTable_length select").val(100);
        $("#dataTable_length select").trigger("change");
    }

不幸的是,该函数强制dataTable在第一页显示所有结果,但模型仍然为leadsList传递null。我认为我必须调用一些dataTable函数来刷新表中的字段,然后表单才能正确提交,但必须有更简单的方法。

总而言之,我总是希望将所有数据从表传递到控制器,而不管我当前在哪个页面上。

DataTable

table = $('#dataTable').DataTable({
                'dom': '<lf<"table_wrapper"t>ip>',
                "aoColumns": [
                { "bSearchable": true },
                { "bSearchable": true },
                { "bSearchable": true },
                { "bSearchable": true },
                { "bSearchable": true },
                { "bSearchable": true },
                { "bSearchable": false },
                { "bSearchable": false },
                { "bSearchable": false },
                { "bSearchable": true }
                ]
            });

当使用分页时,使用DataTable在MVC中提交带有实体的模型失败

找到解决方案了!

首先,我在dataTables js中调整了一个值。

  "aLengthMenu": [ 10, 25, 50, 100, 1000 ].

我加了1000,但你可以加任何你想要的值

在form下,我将输入类型从submit改为button并调用function。

<input type="button" value="Save" onclick="displayAllDataTable()">

我定义了这个函数:

function displayAllDataTable() {
        $("#dataTable_length select").val(1000);
        $("#dataTable_length select").trigger("change");
        $("#dataTableForm").submit();
    }

现在一切正常。

我通读了API文档,并提出了另一个解决方案,通过使用page.len绘制整个表来实现数据绑定。对于包含数千行的大型表,这不是一个理想的解决方案,并且从UI的角度来看,整个表在表单提交给控制器之前绘制,这看起来很奇怪。我还注意到,在控制器端,如果您从Datatable绑定到一个列表,那么绑定/列表的顺序与Datatable的顺序无关。

page.len

这是添加到页面末尾的源代码:

<script>
    $(document).ready(function () {
        $.fn.dataTable.ext.legacy.ajax = true;
        $('#YourTable').dataTable();
    });
    $("#YourTable").submit(function (event) {
        var table = $('#YourTable').DataTable();
        table.page.len(-1).draw();
    });
</script>

基于Adam Bielecki的帖子,我稍微调整了一下,以避免1000长度的选项,如下所示…就用-1吧!

 lengthMenu": [[10, 25, 50, **-1**], [10, 25, 50, "All"]]


function displayAllDataTable() {
            $("#example1_length select").val(**-1**);
            $("#example1_length select").trigger("change");
            $("#groupForm").submit();
}