等待根据模态的响应执行 ajax 请求

Wait to execute ajax request based on response from modal

我想使用模态弹出窗口的响应来中断 ajax 请求,然后根据该响应执行或中止它。

我已经让 beforeSend 正常触发,但是 ajax 请求无论如何都会在我可以对来自模态的用户输入做任何事情之前执行。

理想情况下,ajax 请求不会触发,直到值从 confirmResubmit 返回。

我知道我可能需要使用 ajax.abort(); 来实际停止请求,但我不确定在这种情况下如何实现它。

我意识到我在问如何让 AJAX 同步执行...有没有办法做我想做的事?还是我走错路了?

function readyMyForm() {
  $("#my_button").submit(function(event){
    // prevent html submission
    event.preventDefault();

    // start the spinner
    spinner.spin(document.getElementById("spinner"));

    var myAjaxRequest = $.ajax({
      beforeSend: confirmResubmit(),
      dataType: "json",
      url: $(this).attr('action'),
      method: $(this).attr('method'),
      data: $(this).serialize(),
      timeout: 15000
    });

    myAjaxRequest.done(function(data) {
      if (data.errors) {
        // handle rescued ruby errors
        displayErrors(data.errors);
      } else {
      updateMyPage(data);
      }
    })

    myAjaxRequest.fail(function(jqXHR, textStatus, data) {
      // handle AJAX errors
      displayErrors(textStatus);
    })
  });
}

beforeSend 可以正常调用 confirmResubmit(),但是 AJAX 请求在我到达 debugger;

之前就触发了
function confirmResubmit() {
  var dataFromPage = $(document.getElementById('where-my-data-lives'))[0].dataset.dataIWant;
  if (dataFromPage != null && dataFromPage != "") {
    var confirm = $('#confirmation_modal').foundation('reveal', 'open');
    debugger;
    // do something with returned value from confirm
  };
}

从模态中获取响应是微不足道的,但这里是完整的 JS

  $('#confirm_resubmit').click(function() {
    $('#confirmation_modal').foundation('reveal', 'close');
    true;
  });

  $('#cancel_resubmit').click(function() {
    $('#confirmation_modal').foundation('reveal', 'close');
    false;
  });

所以这是有效的设置 - 以这种方式传递表单属性感觉有点笨拙,但它确实有效。真的比 AJAX 更关注 vanilla JS。

问题'how do I make the AJAX request wait for a response from the user?'的答案是不做。不要中断请求,不要使用beforeSend。相反,只有在收到我想要的响应后才调用 AJAX 请求。

任何试图在弹出窗口中将变量传递到模态的人也可能对此感兴趣。有一段时间我试图弄清楚如何将 formAttributes 传递给 '#confirmation_modal'。我认为答案是从模态内部定位数据,而不是试图在调用时传递数据。

function readyMyForm() {
  $("#my_button").submit(function(event){
    // prevent html submission
    event.preventDefault();

    var formAttributes = [$(this).attr('action'), $(this).attr('method'), $(this).serialize()]
    var dataFromPage = $(document.getElementById('where-my-data-lives'))[0].dataset.dataIWant;
    if (dataFromPage != null && dataFromPage != "") {
      var confirm = $('#confirmation_modal').foundation('reveal', 'open');
    } else {
      // submit AJAX without confirmation if no data already present
      runMyRequest(formAttributes);
    };
  });
}

提取的AJAX函数

function runMyRequest(formAttributes) {
  // start the spinner
  spinner.spin(document.getElementById("spinner"));

  // form attr passed from caller
  var myAjaxRequest = $.ajax({
    dataType: "json",
    url: formAttributes[0],
    method: formAttributes[1],
    data: formAttributes[2],
    timeout: 15000
  });

  myAjaxRequest.done(function(data) {
    if (data.errors) {
      // handle rescued ruby errors
      displayErrors(data.errors);
    } else {
    updatePageData(data);
    }
  });

  myAjaxRequest.fail(function(jqXHR, textStatus, data) {
    // handle AJAX errors
    displayErrors(textStatus);
  });
}

更新处理程序

$('#confirm_resubmit').click(function() {
  // submit AJAX on confirmation
  var formAttributes = [$('#my_form_id').attr('action'), $('#my_form_id').attr('method'), $('#my_form_id').serialize()];
  $('#confirmation_modal').foundation('reveal', 'close');
  runMyRequest(formAttributes);
});