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

ExtJS 3.4按钮点击事件多次触发问题求助

问题根源分析

兄弟,你遇到的这个“点击次数逐次增加、计算结果异常”的问题,本质是重复绑定事件监听器导致的:
每次调用openCustDeposit打开窗口B时,你都会执行dep.grid.custDepositPostBtn.on('click', function(...) {...}),但窗口B是通过closeAction:'hide'隐藏复用的,并没有被销毁。这就导致每打开一次窗口,按钮上就多挂一个点击事件,点击时自然会触发N次(N等于打开次数),算术运算重复执行,结果当然会乱掉!

解决方案

下面给你几个针对性的修复方案,按推荐程度排序:

方案1:将事件绑定移到窗口初始化逻辑中(最优)

既然窗口B是只创建一次、复用多次的,那事件绑定只需要在窗口第一次创建时执行一次就行。把绑定代码移到if (!windep)的分支里:

function openCustDeposit(idCustomer) { 
  require(['view/Deposit'], function (dep) { 
    var windep= Ext.getCmp('windep'); 
    if (!windep) { 
      windep= new Ext.Window({ 
        ... 
        items : [dep.initObj], 
        plain : true, 
        closable: true, 
        closeAction :'hide', 
        ... 
        listeners:{ 
          show:function() { 
            this.loadMask = new Ext.LoadMask(this.body, { msg:'Loading. Please wait...' }); 
          }, 
          destroy:function(){ 
            if(this.mask)delete this.mask; 
          } 
        } 
      }); 
      // 👉 只在窗口第一次创建时绑定事件,避免重复
      dep.grid.custDepositPostBtn.on('click', function(obj,evt) { 
        try { 
          var str_idCrdtMemo='', str_CRApply='', sumCRApply=0; 
          var objGrid = grid; 
          var selRec = objGrid.selModel.getSelected(); 
          .... 
          selRec.set('CustDeposit', sumCRApply); 
          selRec.set('idPostCheck', str_idCrdtMemo.substr(0,str_idCrdtMemo.length-1)); 
          selRec.set('CustDeposit2', str_CRApply.substr(0,str_CRApply.length-1)); 
          .... 
          closeWin(arCustDeposit.grid); // window close 
        } catch (e) { 
          Ext.MessageBox.alert('Error', e); 
        } finally { 
          .... 
        } 
      }); 
    } else { 
      .... 
    } 
    ... 
    windep.show(); 
    ... 
    dep.store.load(); 
  }); 
}

方案2:绑定前先解绑已有监听器

如果因为业务原因,必须每次打开窗口都绑定事件,那绑定前先移除按钮上的已有监听器:
先把事件处理函数抽成独立函数,方便后续精准解绑:

// 抽离独立的事件处理函数,方便解绑
function handleDepositPost(obj, evt) {
  try { 
    var str_idCrdtMemo='', str_CRApply='', sumCRApply=0; 
    var objGrid = grid; 
    var selRec = objGrid.selModel.getSelected(); 
    .... 
    selRec.set('CustDeposit', sumCRApply); 
    selRec.set('idPostCheck', str_idCrdtMemo.substr(0,str_idCrdtMemo.length-1)); 
    selRec.set('CustDeposit2', str_CRApply.substr(0,str_CRApply.length-1)); 
    .... 
    closeWin(arCustDeposit.grid); // window close 
  } catch (e) { 
    Ext.MessageBox.alert('Error', e); 
  } finally { 
    .... 
  }
}

function openCustDeposit(idCustomer) { 
  require(['view/Deposit'], function (dep) { 
    var windep= Ext.getCmp('windep'); 
    if (!windep) { 
      windep= new Ext.Window({ ... }); 
    } else { 
      .... 
    } 
    ... 
    windep.show(); 
    ... 
    dep.store.load(); 
    // 👉 先解绑再绑定,彻底避免重复
    dep.grid.custDepositPostBtn.un('click', handleDepositPost);
    dep.grid.custDepositPostBtn.on('click', handleDepositPost); 
  }); 
}

方案3:使用once绑定单次事件(适合特定场景)

如果每次打开窗口B后,只需要点击一次保存按钮,之后不需要再触发这个事件,可以用once代替on,这样事件只会触发一次,触发后自动解绑:

dep.grid.custDepositPostBtn.once('click', function(obj,evt) { 
  // 原事件逻辑不变
});
额外调试小技巧

后续遇到类似问题时,可以用dep.grid.custDepositPostBtn.hasListener('click')或者查看浏览器开发者工具的元素事件绑定列表,快速确认是否存在重复绑定的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:20:20