2013-05-13 1 views
1

진행률 막대를 사용하여 업로드하는 아약스를 개발 중입니다. 파일 입력이 여러 개가 아니더라도 문제가 없지만 여러 개의 아약스 업로드를 개발하려는 이유 때문에 사용자가 선택한 파일 수가 될 때까지 "for"루프를 만듭니다.for 루프에서 Ajax 변수 i 값을 전체 길이로 변경

여기에 함수가 입력되면 indice의 값은 len 변수의 값입니다. 왜 이런 일이 발생합니까?

myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(indice)) }, false); 

전체 코드는 다음과 같습니다

<script type="text/javascript"> 
    $(document).ready(function(e){ 
     $('#uploader').submit(function(){ 
      var inpf = document.getElementById('files'); 
      var len = inpf.files.length; 
      //console.log(inpf, len);return false; 
      for(var i=0; i<len; i++){ 
       var indice = i; 
       $('div').append('<progress class="prog'+i+'" value="0"></progress><br />'); 
       var formData = new FormData(); 
       formData.append('image', inpf.files[i]); 
       $.ajax({ 
        url: 'upload1.php', //server script to process data 
        type: 'POST', 
        xhr: function() { // custom xhr 
         var myXhr = $.ajaxSettings.xhr(); 
         if(myXhr.upload){ // check if upload property exists 
          myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(indice)) }, false); // for handling the progress of the upload 
         } 
         return myXhr; 
        }, 
        //Ajax events 
        //beforeSend: beforeSendHandler, 
        success: function(data){ 
         completeHandler(data, '.prog'+i); 
        }, 
        //error: errorHandler, 
        // Form data 
        data: formData, 
        //Options to tell JQuery not to process data or worry about content-type 
        cache: false, 
        contentType: false, 
        processData: false, 
       }); 
      } 
      return false; 
     }); 
    }); 

    function progressHandlingFunction(e, klass){ 
     if(e.lengthComputable){ 
      $(klass).attr({value:e.loaded, max:e.total}); 
     } 
    } 

    function completeHandler(data, klass){ 
     $(klass).attr({value:0}); 
    } 
</script> 

당신은 예와 함께 jsFiddle 있습니다 http://jsfiddle.net/Pgq9s/

+0

내가 어떤 오류가 표시되지 않았다. 잘 작동하는 것 같습니다. – Christian

답변

2

i 변수는 for 루프의 특정 반복이 아니라 전체 함수에 적용됩니다. success 콜백 함수가 실행될 때까지 for 루프가 전체적으로 실행되고 i은 최종 반복 이후의 값과 같습니다 (따라서 i == len).

는 반복에 대해 i의 가치를 보존, 클로저를 생성하는 즉시 호출 함수 표현식을 사용

for(var i=0; i<len; i++){ 
    var indice = i; 
    $('div').append('<progress class="prog'+i+'" value="0"></progress><br />'); 
    var formData = new FormData(); 
    formData.append('image', inpf.files[i]); 
    (function(index) { 
    $.ajax({ 
     url: 'upload1.php', //server script to process data 
     type: 'POST', 
     xhr: function() { // custom xhr 
      var myXhr = $.ajaxSettings.xhr(); 
      if(myXhr.upload){ // check if upload property exists 
       myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(index)) }, false); // for handling the progress of the upload 
      } 
      return myXhr; 
     }, 
     //Ajax events 
     //beforeSend: beforeSendHandler, 
     success: function(data){ 
      completeHandler(data, '.prog'+index); 
     }, 
     //error: errorHandler, 
     // Form data 
     data: formData, 
     //Options to tell JQuery not to process data or worry about content-type 
     cache: false, 
     contentType: false, 
     processData: false, 
    }); 
    })(i); 
} 
+0

'wrapping'의 크기를 줄여서 'xhr' 속성의 값에 대한 함수를 생성하기 만하면 즉시 평가할 수 있습니다. – sje397

+0

@ sje397'xhr' 함수는'i'의 값을 사용하는 유일한 함수가 아니며'success' 콜백에도 사용됩니다. 그것이 사실이 아니더라도, 나는 그것을 줄이는 것이 어떤 이익이 될지 확신하지 못합니다. –

+0

충분합니다. 가독성을 위해 이러한 것들을 가능한 한 작게하고 싶습니다. 인덱스를 가져 와서 '$ ajax'에 전달 된 객체를 반환하는 또 다른 함수를 작성하는 것으로 넘어가는 경향이 있습니다. 가독성을 위해서입니다. – sje397

2

루프는 아약스 많은 요청을 시작합니다. 모든 요청이 시작되면 i이 최대 값으로 설정됩니다.

그러면 ajax 요청의 결과가 들어 오기 시작하고 success 콜백 함수가 실행됩니다. i은 여전히 ​​모든 콜백이 실행될 때 최대 값이됩니다.

관련 문제