You need to enable JavaScript to run this app. Angular中ng-click绑定div函数 单次点击触发执行两次问题
优惠活动
大模型
产品
解决方案
定价
更多

Angular中ng-click绑定div函数 单次点击触发执行两次问题

问题描述

我在Web应用中使用Angular框架,在div标签上通过ng-click绑定函数来修改复选框的值,但点击该div时绑定的函数会执行两次。

HTML代码

<div class="switch" ng-click="f_changeSwitch(a_Order.isInSaloon)">
    <label>
        <span>{{lang==1  ? 'سالن' : 'Saloon'}}</span>
        <input ng-model="a_Order.isInSaloon" type="checkbox">
        <span class="lever lever_c"></span>
        {{lang==1  ? 'بیرون بر' : 'Take Away'}}
    </label>
</div>

JavaScript代码

$scope.f_changeSwitch = function (saloon) {
    console.log("counter", counter);
    console.log("saloon", saloon);
    console.log("$scope.a_Order.isInSaloon", $scope.a_Order.isInSaloon);
    if ($scope.a_Order.isInSaloon == true) {
        $scope.a_Order.isInSaloon = false;
    } else {
        $scope.a_Order.isInSaloon = true;
    }
    if ($scope.a_Order.isInSaloon == false) {
        $scope.packAge_Cost = {};
        $scope.packAge_Cost.a_tProductId_packageCost = $scope.a_tProductId_packageCost;
        $scope.packAge_Cost.t = $scope.a_prName;
        $scope.packAge_Cost.a_prName_EN = $scope.a_prName_EN;
        $scope.packAge_Cost.total = $scope.packAgeCostInNumber;
        $scope.ordered_item.push($scope.packAge_Cost)
        $scope.a_invTotal = $scope.a_invTotal + $scope.packAgeCost
        $scope.a_invTotalString = f_Cash2String($scope.a_invTotal);
        console.log("$scope.packAgeCost1234", $scope.packAgeCost);
    } else {
        $scope.a_invTotal = $scope.a_invTotal - $scope.packAgeCost; 
        $scope.a_invTotalString = f_Cash2String($scope.a_invTotal);
        console.log("is in saloon is true now")
    }
    counter++
}

运行现象

单次点击后计数变为2,控制台日志显示绑定的函数被触发两次。


触发原因

两次执行的根源是原生label默认行为+事件冒泡+ng-model双向绑定的逻辑叠加:

  1. 外层带switch类的div本身绑定了ng-click,点击该区域时首先会触发f_changeSwitch执行一次。
  2. div内部嵌套了<label>标签,原生label的默认逻辑是:点击label内任意区域,都会触发其关联的表单元素(也就是绑定了同一个a_Order.isInSaloon的checkbox)的点击事件。
  3. f_changeSwitch内部手动修改了$scope.a_Order.isInSaloon的值,同时checkbox的ng-model已经绑定了该值,事件冒泡过程中checkbox的原生点击会再次翻转状态,最终相当于事件被两层触发,导致函数执行两次。
    另外现有代码存在冗余:f_changeSwitch里手动翻转isInSaloon的逻辑完全多余,checkbox本身绑定ng-model后,用户点击即可自动更新对应的值。

解决方案

按改动量从小到大选即可:

  • 最小改动:阻止事件冒泡
    给内层的checkbox加上ng-click="$event.stopPropagation()",阻断label到外层div的事件冒泡,避免双层触发。
    <input ng-model="a_Order.isInSaloon" type="checkbox" ng-click="$event.stopPropagation()">
    
  • 优化方案:移除外层多余的逻辑绑定
    既然已经用checkbox绑定了ng-model,完全不需要在div上绑ng-click来手动修改值,直接把状态变更的副作用逻辑(比如修改总价、添加打包费的部分)挪到ng-change指令上即可,ng-change会在isInSaloon的值真正变更时才触发,不会出现重复执行的问题:
    <div class="switch">
        <label>
            <span>{{lang==1  ? 'سالن' : 'Saloon'}}</span>
            <input ng-model="a_Order.isInSaloon" type="checkbox" ng-change="f_changeSwitch()">
            <span class="lever lever_c"></span>
            {{lang==1  ? 'بیرون بر' : 'Take Away'}}
        </label>
    </div>
    
    同时把JS里手动翻转isInSaloon的代码删掉,避免重复改值:
    $scope.f_changeSwitch = function () {
        // 此处删除原有手动翻转isInSaloon的if判断代码,该值已由ng-model自动更新
        if ($scope.a_Order.isInSaloon == false) {
            $scope.packAge_Cost = {};
            $scope.packAge_Cost.a_tProductId_packageCost = $scope.a_tProductId_packageCost;
            $scope.packAge_Cost.t = $scope.a_prName;
            $scope.packAge_Cost.a_prName_EN = $scope.a_prName_EN;
            $scope.packAge_Cost.total = $scope.packAgeCostInNumber;
            $scope.ordered_item.push($scope.packAge_Cost)
            $scope.a_invTotal = $scope.a_invTotal + $scope.packAgeCost
            $scope.a_invTotalString = f_Cash2String($scope.a_invTotal);
        } else {
            $scope.a_invTotal = $scope.a_invTotal - $scope.packAgeCost; 
            $scope.a_invTotalString = f_Cash2String($scope.a_invTotal);
        }
    }
    
  • 兜底方案:添加防抖判断
    如果因业务限制无法修改现有绑定逻辑,就在函数开头加时间戳判断,短时间内的重复触发直接拦截:
    let lastClickTime = 0;
    $scope.f_changeSwitch = function (saloon) {
        const now = Date.now();
        // 200毫秒内的重复触发直接返回
        if (now - lastClickTime < 200) return;
        lastClickTime = now;
        // 原有业务逻辑正常执行
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 14:15:01