如何通过Ajax仅提交表单修改数据而非全部数据至控制器
只提交DataTable中修改过的行数据
没问题,这种批量提交场景下确实没必要把所有150行都发回去,只需要收集用户实际修改过的TagValue及其对应的Id就可以大幅减少数据量,提升提交速度。下面给你两种实用的实现方案:
方案一:实时标记修改状态,提交时筛选
这种方法会在用户修改输入框时实时标记,提交时直接提取标记过的行数据,直观且高效。
步骤1:给输入框添加原始值标记
在渲染TagValue输入框时,增加一个data-original-value属性存储初始值,方便后续对比:
@Html.EditorFor(m => Model.tags[i].TagValue, new { htmlAttributes = new { @id = "TagVaule_" + Model.tags[i].Id, @class = "form-control", data_original_value = Model.tags[i].TagValue <!-- 新增:存储初始值 --> } })
步骤2:绑定change事件标记修改项
页面加载完成后,给所有TagValue输入框绑定change事件,当值发生变化时添加标记类:
$(document).ready(function() { // 给所有TagValue输入框绑定修改监听 $('#myTable .form-control').on('change', function() { const originalVal = $(this).data('original-value'); const currentVal = $(this).val(); if (currentVal !== originalVal) { $(this).addClass('modified'); // 给输入框加修改标记 $(this).closest('tr').addClass('row-modified'); // 给整行加修改标记(可选) } else { $(this).removeClass('modified'); $(this).closest('tr').removeClass('row-modified'); } }); });
步骤3:提交时只收集修改过的数据
修改表单提交事件,只提取带modified类的输入框对应的Id和值,同时带上AntiForgeryToken:
$('#share').on('submit', function (e) { e.preventDefault(); const modifiedData = []; const token = $('input[name="__RequestVerificationToken"]'); // 遍历所有修改过的输入框 $('#myTable .modified').each(function(index) { const $row = $(this).closest('tr'); const tagId = $row.find('input[type="hidden"]').val(); // 获取对应Id const tagValue = $(this).val(); // 获取修改后的值 // 按后端模型绑定的格式构造数据(这里假设后端接收List<ModifiedTagDto>) modifiedData.push({ name: `modifiedTags[${index}].Id`, value: tagId }); modifiedData.push({ name: `modifiedTags[${index}].TagValue`, value: tagValue }); }); // 添加AntiForgeryToken modifiedData.push({ name: token.attr('name'), value: token.val() }); // 提交Ajax请求 $.ajax({ type: 'POST', url: '@Url.Action("BulkUpdate", "Home")', data: modifiedData, success: function (data) { $('#myModalContent').html(data); $('#myModal').modal('show'); // 提交成功后重置标记和原始值 $('#myTable .modified').removeClass('modified'); $('#myTable .row-modified').removeClass('row-modified'); $('#myTable .form-control').each(function() { $(this).data('original-value', $(this).val()); }); } }); });
后端对应处理
创建一个DTO类接收修改数据,然后在Action中处理:
// DTO类:仅包含需要修改的字段 public class ModifiedTagDto { public int Id { get; set; } public string TagValue { get; set; } } [HttpPost] public ActionResult BulkUpdate(List<ModifiedTagDto> modifiedTags) { // 仅遍历修改过的项执行更新逻辑 foreach (var tag in modifiedTags) { // 示例:更新数据库中对应Id的TagValue var targetTag = _dbContext.Tags.Find(tag.Id); if (targetTag != null) { targetTag.TagValue = tag.TagValue; } } _dbContext.SaveChanges(); return PartialView("UpdateResult"); // 返回结果视图 }
方案二:提交时批量对比初始值(无需实时标记)
如果不需要实时显示哪些行被修改,可以在页面加载时保存所有初始数据,提交时一次性对比差异,代码更简洁:
步骤1:页面加载时保存初始数据
$(document).ready(function() { // 存储所有Tag的初始Id和Value到对象中 window.originalTags = {}; $('#myTable tr').each(function() { const tagId = $(this).find('input[type="hidden"]').val(); const tagValue = $(this).find('.form-control').val(); window.originalTags[tagId] = tagValue; }); });
步骤2:提交时对比并收集修改数据
$('#share').on('submit', function (e) { e.preventDefault(); const modifiedTags = []; const token = $('input[name="__RequestVerificationToken"]').val(); // 遍历所有行,对比当前值和初始值 $('#myTable tr').each(function() { const tagId = $(this).find('input[type="hidden"]').val(); const currentValue = $(this).find('.form-control').val(); if (currentValue !== window.originalTags[tagId]) { modifiedTags.push({ Id: tagId, TagValue: currentValue }); } }); // 用JSON格式提交(需要后端配置FromBody接收) $.ajax({ type: 'POST', url: '@Url.Action("BulkUpdate", "Home")', data: JSON.stringify({ modifiedTags: modifiedTags, __RequestVerificationToken: token }), contentType: 'application/json; charset=utf-8', headers: { // 可选:把AntiForgeryToken放在请求头中,更规范 'RequestVerificationToken': token }, success: function (data) { $('#myModalContent').html(data); $('#myModal').modal('show'); // 更新初始数据,避免下次提交误判 window.originalTags = {}; $('#myTable tr').each(function() { const tagId = $(this).find('input[type="hidden"]').val(); const tagValue = $(this).find('.form-control').val(); window.originalTags[tagId] = tagValue; }); } }); });
后端对应处理
调整Action用[FromBody]接收JSON数据:
public class BulkUpdateRequest { public List<ModifiedTagDto> ModifiedTags { get; set; } public string __RequestVerificationToken { get; set; } } [HttpPost] public ActionResult BulkUpdate([FromBody] BulkUpdateRequest request) { // 验证AntiForgeryToken(如果放在请求头,需要对应配置) // 执行更新逻辑... return PartialView("UpdateResult"); }
这两种方案都能有效减少提交的数据量,解决回发延迟问题,你可以根据是否需要实时标记修改状态来选择~
内容的提问来源于stack exchange,提问作者user11974227
相关产品推荐
相关产品推荐

