简体   繁体   中英

Why is this callback handler being called twice?

So I have the following JavaScript code. When the user clicks a button on the page, it reads the "name" and "stepId" from data attributes, and then opens a Twitter bootstrap modal dialog. When the "Clear" button is clicked on the dialog, it fires the supplied callback.

This works great the first time it is invoked. The problem is that on all subsequent invocations, when clicking the "Clear" button, the callback is fired twice. On the first callback we see the stepId from the first invocation, and on the second callback we see the stepId from the current invocation.

clearInputTargetName and clearInputName are always the correct value in the dialog.

var Dialog = function (dlgId)
{
   var okCallback = null;

   var show = function (cb)
   {
      okCallback = cb;

      jQuery.noConflict();
      $(dlgId).modal("show");
   };

   var hide = function ()
   {
      jQuery.noConflict();
      $(dlgId).modal("hide");
   };

   var onOK = function ()
   {
      okCallback();
   };

   var init = function ()
   {
      $(dlgId + " .okButton").off('click').on('click', function ()
      {
         onOK(true);
         hide();
      });
   };

   init();

   return {
      show: show,
      hide: hide,
      init: init
   };
};

var ClearInputDialog = function ()
{
   var show = function (input, cb)
   {
      var dlg = new Dialog("#clearInputDialog", input);

      $("#clearInputTargetName").text(input);
      $("#clearInputName").text(input);

      dlg.show(function ()
      {
         cb(true);
         dlg.hide();
      });
   };

   return { show: show };
};

var WorkflowDesignerVM = function ()
{
   var clearInput = function ()
   {
      var name = $(this).attr("data-input");
      var stepId = $(this).attr("data-stepid");

      var dlg = new ClearInputDialog();
      dlg.show(name, function (result)
      {
         alert('clearing stepId: ' + stepId);
      });
   };

   var init = function ()
   {
      $(document).on("click", ".clear-input", clearInput);
   };

   init();
};

var vm = new WorkflowDesignerVM();

And the modal dialog looks like this:

<div id="clearInputDialog" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title">Clear Input for <span id="clearInputTargetName">[clearInputTargetName]</span></h4>
      </div>
      <div class="modal-body">
            Are you sure you want to clear <span id="clearInputName">[clearInputName]</span>?
        </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default cancelButton" data-dismiss="modal">Close</button>
        <button type="button" id="clearInputButton" class="btn btn-primary okButton" data-stepid="" data-input="">Clear</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

I have a feeling it has something to do with my jQuery event handler code. If I change the Dialog.init to the following code, then we always get one callback, but we always see the stepId from the first invocation.

var init = function ()
{
   $(dlgId + " .okButton").on('click', function ()
   {
      onOK(true);
      hide();

      $(dlgId + " .okButton").off('click');
   });
};

Try adding event stop propagation within your click function, as well as, add return false. This will stop any event propagation or double invocations. Also, rather than using off().on()... try just .live() and then, use off() when you are ready to remove the click event when the click is not available for the user, as well as, remove it from memory.

$(dlgId + " .okButton").live('click', function (event) {
  event.stopImmediatePropagation(); 
  event = null;
  onOK(true);
  hide();
  return false;
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM