当使用分页时,使用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 }
]
});
找到解决方案了!
首先,我在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();
}