如何重构代码以使Bootstrap的模态方法使用回调异步?

时间:2014-12-22 03:30:38

标签: jquery twitter-bootstrap twitter-bootstrap-3 modal-dialog bootstrap-modal

我在网站上使用 Bootstrap v3.3.0 。我正在使用 Bootstrap框架的模态对话框功能。

我已经为表单提交编写了一个jQuery-AJAX函数,如下所示:

$('#rebate_request_form').submit(function(e) {  
  $('#rebateModal').modal('hide');
  $('#progressModal').modal('show');   

  var fileInput = $("#receipt_image")[0];  
  var input =  $("#receipt_image").val(); 

  var form = $(this);

  var formdata = false;

  if(window.FormData) {
    formdata = new FormData(form[0]);
  }  

  if(input != '') {
    var ImgSizeInBytes = fileInput.files[0].size;  
    var filename = $('input[type=file]').val().split('\\').pop();
    var customer_id = $('#customer_id').val();
  }  
  if(input!='' && ImgSizeInBytes > 10485760) {
    var trans_id = $('#trans_id').val();  
    var trans_date_dateLists_year_list = $("#trans_date_dateLists_year_list").val();
    var trans_date_dateLists_month_list = $("#trans_date_dateLists_month_list").val();
    var trans_date_dateLists_day_list = $("#trans_date_dateLists_day_list").val();  

    var params = "trans_id="+trans_id+"&trans_date_dateLists_day_list="+trans_date_dateLists_day_list+"&trans_date_dateLists_month_list="+trans_date_dateLists_month_list+"&trans_date_dateLists_year_list="+trans_date_dateLists_year_list+"&file_size="+ImgSizeInBytes+"&file_name="+filename+"&customer_id="+customer_id;
    var method = 'GET';
  } else {
    var params = formdata ? formdata : form.serialize();
    var method = 'POST';
  }  

  var formAction = form.attr('action');

  $.ajax({
    url         : 'rebate_request.php',
    type        : method,    
    cache       : false,
    data        : params,
    contentType : false,
    processData : false,

    success: function(response) {
      $('#progressModal').modal('hide');
      var responseObject = $.parseJSON(response);    
      if(responseObject.error_message) {
        $('#rebateModal').modal('show');  
        if ($(".alert-dismissible")[0]) {
          $('.alert-dismissible').remove();   
        }  
        var htmlString = "<div class='alert alert-danger alert-dismissible' role='alert'><button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;</button>"+responseObject.error_message+"</div>";    
        $(htmlString).insertBefore('div.modal-body #rebate_request_form');        
        } else { 
          $('#successModal').modal('show');       
        }
      }
    });
    e.preventDefault();
  });

上述功能正常运行,但有时在响应中收到error_message时,模式ID为id&#34; rebateModal&#34; 不会显示。虽然有时在某​​些浏览器中我不会遇到这个问题,但一切都运行得很顺利。

所以我想重构我的代码,关于使用Bootstrap函数回调调用模态方法,如下所示:

$('#rebateModal').one('hidden.bs.modal', function () {
  $('#progressModal').one('shown.bs.modal', function () {
  //...more code...
  }).modal('show');
}).modal('hide');

但我无法以上述方式编写代码,因为我是Bootstrap框架和JS的新手。

有人可以帮我重构我使用Bootstrap函数回调编写的代码吗?

如果您需要有关Bootstrap中函数回调的更多信息,请参阅以下链接: Link for Bootstrap Modal functionality

提前致谢。

1 个答案:

答案 0 :(得分:2)

我认为既然您想要使用回调函数,那么您的怀疑是在提交函数中的调用之间可能存在竞争条件(可能是由于在动画中花费的时间):

$('#rebateModal').modal('hide');

AJAX成功函数中的调用(当响应包含error_message时):

$('#rebateModal').modal('show');

在这种情况下,一种可能的实现方式是:

$( '#rebate_request_form' ).submit( function(e) {
    $( '#rebateModal' ).one( 'hidden.bs.modal', function () {
        $('#progressModal').one( 'shown.bs.modal', function () {
            var fileInput = $("#receipt_image")[0];  
            var input =  $("#receipt_image").val(); 

            var form = $( '#rebate_request_form' );

            var formdata = false;

            if( window.FormData ) {
                formdata = new FormData( form[0] );
            }  

            if(input != '') {
                var ImgSizeInBytes = fileInput.files[0].size;  
                var filename = $('input[type=file]').val().split('\\').pop();
                var customer_id = $('#customer_id').val();
            }  
            if(input!='' && ImgSizeInBytes > 10485760) {
                var trans_id = $('#trans_id').val();  
                var trans_date_dateLists_year_list = $("#trans_date_dateLists_year_list").val();
                var trans_date_dateLists_month_list = $("#trans_date_dateLists_month_list").val();
                var trans_date_dateLists_day_list = $("#trans_date_dateLists_day_list").val();  

                var params = "trans_id="+trans_id+"&trans_date_dateLists_day_list="+trans_date_dateLists_day_list+"&trans_date_dateLists_month_list="+trans_date_dateLists_month_list+"&trans_date_dateLists_year_list="+trans_date_dateLists_year_list+"&file_size="+ImgSizeInBytes+"&file_name="+filename+"&customer_id="+customer_id;
                var method = 'GET';
            } else {
                var params = formdata ? formdata : form.serialize();
                var method = 'POST';
            }  

            var formAction = form.attr('action');

            $.ajax( {
                url         : 'rebate_request.php',
                type        : method,    
                cache       : false,
                data        : params,
                contentType : false,
                processData : false,

                success: function(response) {
                    $('#progressModal').one( 'hidden.bs.modal', function () {
                        var responseObject = $.parseJSON(response);    
                        if(responseObject.error_message) {
                            $('#rebateModal').modal('show');  
                            if ($(".alert-dismissible")[0]) {
                                $('.alert-dismissible').remove();   
                            }  
                            var htmlString = "<div class='alert alert-danger alert-dismissible' role='alert'><button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;</button>"+responseObject.error_message+"</div>";    
                            $(htmlString).insertBefore('div.modal-body #rebate_request_form');        
                        } else { 
                            $('#successModal').modal('show');       
                        }
                    } ).modal('hide');
                }
            });
        } ).modal( 'show' );
    } ).modal( 'hide' );
    e.preventDefault();
} );

只有在隐藏回调完成后才进行AJAX调用(一旦隐藏动画完成就应该进行),你可以消除AJAX调用返回的可能竞争条件,其错误比模态隐藏动画更快。 / p>

这只是一个粗略的实施。您可能还想将内部代码拉出到可以按名称调用的单独函数中。这将允许您包装一些初始逻辑来处理各种场景(例如,如果在调用表单提交函数时#rebateModal不可见)