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

基于单选框选择的Ajax请求后复选框选中状态异常问题

问题解决:单选按钮快速切换导致复选框状态异常

问题场景

我有一组复选框,其选中/未选中状态由3个单选按钮控制。单选按钮切换时会发起Ajax请求,根据单选按钮的值确定哪些复选框需要选中。但快速切换两个单选按钮时,最终选中的复选框会同时包含两个单选按钮对应的选项:

  • 选中“manager”时,复选框仅显示manager对应的选项;
  • 选中“test”时,复选框仅显示test对应的选项;
  • 快速选中“manager”再选“test”后,复选框同时包含manager和test的选项,但最后选中的是“test”,应该只保留test对应的复选框状态。

原代码

$(document).on("change", "input[type=radio][name=\"user[profile]\"]", function (){

        let value = $( this ).val();
        let data = {profile_id: value}
        let url = HOME_URL + '/API/getmodules/' + value

        $('input:checkbox[id^=\"user_access_\"]').prop('checked', false) //initialize all checkboxes at uncheck
        $('span[class^=\"badge badge-success\"]:not([id^=\"span-example\"])').contents().unwrap();

        $.post(url, data).then(function (response)
        {

            let modulesData = response.modules
            for (let module in modulesData){
                let moduleValue = modulesData[module].id

                let $modules = $('input:checkbox[id^=\"user_access_\"][value=' + moduleValue + ']')
                let $modulesLabel = $('label[for=\"user_access_' + modulesData[module].toolId + '_' + moduleValue + '\"]')

                $modules.prop('checked', true) // check the checkboxes depends on the data response
                $modulesLabel.empty();
                $modulesLabel.append('<span class="badge badge-success">' + modulesData[module].name + '</span>');
            }

        })

    })

问题原因

这是典型的Ajax竞态条件问题:快速切换单选按钮时,前一次的Ajax请求还未完成,后一次请求已触发并执行了复选框清空操作,但前一次请求的响应后续返回后,会再次勾选其对应的选项,最终导致两次请求对应的复选框选项都被选中。

解决方案

维护一个Ajax请求的引用,每次触发新的请求前,终止上一次未完成的请求,确保只有最后一次请求的响应会处理复选框状态。

修改后的代码

// 维护全局请求引用,用于终止未完成的请求
let pendingRequest = null;

$(document).on("change", "input[type=radio][name=\"user[profile]\"]", function (){
    let value = $(this).val();
    let data = {profile_id: value};
    let url = HOME_URL + '/API/getmodules/' + value;

    // 如果有未完成的请求,先终止它
    if (pendingRequest) {
        pendingRequest.abort();
        pendingRequest = null;
    }

    // 清空所有复选框状态和标签样式
    $('input:checkbox[id^=\"user_access_\"]').prop('checked', false);
    $('span[class^=\"badge badge-success\"]:not([id^=\"span-example\"])').contents().unwrap();

    // 发起新请求并保存引用
    pendingRequest = $.post(url, data).then(function (response) {
        let modulesData = response.modules;
        for (let module in modulesData){
            let moduleValue = modulesData[module].id;
            let $modules = $('input:checkbox[id^=\"user_access_\"][value=' + moduleValue + ']');
            let $modulesLabel = $('label[for=\"user_access_' + modulesData[module].toolId + '_' + moduleValue + '\"]');

            $modules.prop('checked', true);
            $modulesLabel.empty();
            $modulesLabel.append('<span class="badge badge-success">' + modulesData[module].name + '</span>');
        }
    }).always(function() {
        // 请求完成(成功/失败)后清空引用
        pendingRequest = null;
    });
});

关键修改说明

  • 新增pendingRequest变量存储当前未完成的Ajax请求引用;
  • 每次触发单选按钮变更时,先检查并终止未完成的请求,避免旧请求的响应干扰新状态;
  • 使用always方法确保无论请求成功或失败,都清空请求引用,避免影响后续操作。

内容的提问来源于stack exchange,提问作者Lino

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:45:31