You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:09:33