2016-11-02 24 views
0

データをデータベースにインポートするためにスプレッドシートをアップロードしています。挿入する前に、各値についていくつかのサーバー側の検証を実行します。jQueryが完了する前にアニメーションが完了するまで待つ

IはサーバにファイルをアップロードするためにjqueryのAJAXを使用して、Iは

var errored = false; 
var items = []; 
var width; 
var percent; 

$("#uploadForm").ajaxForm({ 
    dataType: 'json', 
    beforeSubmit: function() { 
     errored = false; 
     width = 0; 
     percent = 0; 
    }, 
    beforeSend: function() { //before sending form 
     $('#upload-progress').show(); 
    }, 
    uploadProgress: function(event, position, total, percentComplete) { //on progress 
     $('#load').width(percentComplete + '%') //update progressbar percent complete 
     $('#load').html(percentComplete + '%'); //update status text 
    }, 
    success: function(response) { 
     var size = Object.keys(response.items).length + 1; 
     //this will trigger the first callback. 
     var base = $.when({}); 
     var promises = []; 

     percent = 100/Object.keys(response.items).length; 

     $('#validate-progress').show(); 
     $('#UploadButton').html('<i class="fa fa-cog fa-spin fa-fw"></i> Validating Data'); 

     $.each(response.items, function(key, item) { 
      var last = (key == size) ? true : false; 

      promises.push(base = base.then(getAjaxDeferred(key, item, last))); 
     }); 
    }, 
    complete: function() { 
     $('#load').width('0%'); //update progressbar percent complete 
     $('#upload-progress').hide(); 
     $(this).clearForm(); 
    } 
}); 

Iは、ループの各列のそれぞれを介して多次元配列の形でバック処理されたデータの応答を取得します配列を作成し、ajaxを使用するjquery関数に渡し、次の行を送信する前に完了するまで延期します。

function getAjaxDeferred(row, item, last) { 
    return function() { 
     // wrap with a deferred 
     var defer = $.Deferred(); 
     $.ajax({ 
      url: 'path/to/file', 
      method: 'POST', 
      data: { 
       row: row, 
       item: item 
      }, 
      dataType: 'json', 
      success: function(response) { 

       $('<p>' + response.description + ' <i class="fa fa-check"></i></p>').appendTo('#inserted-rows'); 
       items.push(response.item);     

       if(last) { 
        $('<p class="last-insert">All done!!</p>').appendTo('#inserted-rows'); 

        if(errored) { 
         $('#myModal-errors').modal('show'); 
        } 
       } 
       width = width + percent; 
       $('#validating').width(width + '%').html((Math.round(width * 10)/10).toFixed(0) + '%'); 
       $('#inserted-rows').show().animate({ scrollTop: $('#inserted-rows').prop("scrollHeight") - $('#inserted-rows').height() }, 'fast'); 
      }, 
      complete: function() { 
       // resolve when complete always. Even on failure we 
       // want to keep going with other requests 
       defer.resolve(); 
      } 
     }); 
     // return a promise so that we can chain properly in the each 
     return defer.promise(); 
    }; 
} 

(それは生産より多く遅くだから)すべては私が私の開発サーバ上で欲しい正確にどのように動作し、行が関数に送られ、それがサーバー上で検証し、出力DIVへの応答を追加し、進捗状況を更新バーの幅をパーセンテージで表し、最後の行であればエラーが見つかった場合はモーダルを表示します。

プロダクションサーバーで問題が発生するのは、速いため、プログレスバーがアニメーションよりも速く更新されるため、すぐに完了し、アニメーションが完了する前にモーダルが表示されるためです。

最後の行が処理されるまでモーダルを停止したアニメーションにcomplete:function()を追加しようとしましたが、プログレスバーの更新が速すぎると助けになりませんでした。

アニメーションが終了するまで待ってから最後の行が処理されるまでモーダルを待機させるにはどうすればよいですか?

$('#inserted-rows').show().stop(false, true).animate({.... 

この完全な現在のアニメーションすぐに次のいずれかを開始する前に:

+0

'animate()'のコールバックに 'defer.resolve()'を入れてみてください –

+0

アニメーションの前に['stop(false、true)'](https://api.jquery.com/stop/) ()は次のアニメーションを開始する直前に現在のアニメーションを完成させます。 –

+0

'応答。 items'は数字キーを持っているようです。 –

答えて

1

stop(false, true)animate()前に試してみてください。それ以外の場合、アニメーションはキューに入れられ、1つ後に実行されます。

関連する問題