2017-05-15 39 views
0

我在XML文件中定義了各種HTML元素。 我不能夠顯示我的XML元素作爲整體,但它有多行,每行包含複選框,文件上傳選項等。如何確保File使用Javascript完全由FileReader讀取

我正在使用Javascript獲取這些元素,然後使用XMLHTTPRequest發送這些請求到控制器進行處理。

想象HTML元素是象下面這樣:

Row1 ---- Checkbox1_Row1 TextDescription_Row1  FileUpload_Row1  
Row2 ---- Checkbox1_Row2 TextDescription_Row2  FileUpload_Row2  

我可以有多少曾經的行越好。

使用Javascript,我得到所有這些表單元素,這些元素通過行號(Row1,Row2)進行區分。

我通過每個表單元素循環,然後

for(var j=0; j< formelements.length; j+++) 
{ 
    if (formElements[j].type == "textbox") 
    { 
     Do something 
    } 
    elseif (formElements[j].type == "file") 
    { 
     var Base64String; 
     var ready = false; 
     var fileName = formElements[j].files[0].name; 

     var check = function() { 
     if (ready === true) {    
     array.push(Base64String);       
     return; 
     } 
     setTimeout(check, 1000); 
     } 

     check(); 

     var reader = new FileReader(); 
      reader.onloadend = function (evt) { 
      Base64String = evt.target.result; 
      ready = true; 
      }; 
     reader.readAsDataURL(file); 
     } 
    } 

我使用的陣列推對應於各行並與最終值的陣列的一些改變之後將被髮送到控制器的所有值。這裏是文件上傳選項,我從每一行讀取文件並將它們轉換爲二進制格式併發送到控制器。如果只有一行,這種方法可以正常工作。當有多行時,這種方法會發生什麼,當循環遍歷表單元素時,它檢查第一行(比如文本框)的所有內容,並將其放入數組中,但是當它是文件類型時,它會進入循環並讀取文件。讀取文件需要一些時間,並通過時間循環轉到下一個表單元素(這不過是Row2)。現在Row2表單元素進入圖片並說,我們不上傳任何文件,它將爲空。現在check()函數完成並且row1中的文件被完全讀取。由於循環已經在第2行表單元素中,所以此文件值將從空值中分配給Row2。因此,Row2在文件類型方面將具有空值和文件值,但Row1沒有值。同樣,如果我在多行中有多個文件,則根據FileReader讀取的時間將文件值分配給當前循環中存在的任何行表單元素。

我需要確保文件值被完全讀取,然後再轉到下一個表單元素。如何實現這一目標?

************************更新********************* *

這裏所說的標記爲複製的問題只有文件類型進來,因此它們可以循環訪問文件類型。對我來說,表單元素由Checkbox1_Row1,TextDescription_Row1,FileUpload_Row1,Checkbox1_Row2,TextDescription_Row2,FileUpload_Row2組成。

我必須確保FileUpload_Row1在從文件中讀取正確的值之後才能移動到下一個表單元素,這裏是Checkbox1_Row2。

+0

'.push()''Base64String'到''內array' onloadend'回電話。 – guest271314

+0

我曾嘗試過,但仍面臨同樣的問題。 –

+0

你可以創建一個stacksnippets或plnkr http://plnkr.co來演示問題嗎? – guest271314

回答

1

evt應該是eventevt.target.result.push()event.target.resultfileList陣列,做的東西時fileList.length等於count

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script> 
 
    function myFunction() { 
 
     var files = Array.prototype.map.call(
 
     document.querySelectorAll("[id^=myFile]") 
 
     , function(input) { 
 
      return {id:input.dataset.id, file: input.files[0]}; 
 
     }); 
 

 
     var count = files.length; // total number of files 
 
     var fileList = []; // accepted files 
 

 
     for (var i = 0; i < count; i++) { 
 
     var file = files[i].file; 
 
     var id = files[i].id; 
 
     var filename = files[i].file.name; 
 
     if (i >= count) { 
 
      break; 
 
     } 
 

 
     var reader = new FileReader(); 
 

 
     reader.onload = (function(id, filename) { 
 
      return function(event) { 
 
      fileList.push({id, filename, file:event.target.result}); { 
 
       if (fileList.length === count) { 
 
       // do stuff with `fileList` 
 
       console.log(fileList); 
 
       } 
 
      } 
 
      } 
 
     })(id, filename); 
 
     reader.readAsDataURL(file); 
 
     } 
 
    } 
 
    </script> 
 
</head> 
 

 
<body> 
 
    <h1>Hello Plunker!</h1> 
 
    <input type="file" id="myFile_row1" data-id="A"> 
 
    <input type="file" id="myFile_row2" data-id="B"> 
 
    <input type="file" id="myFile_row3" data-id="C"> 
 

 
    <button onclick="myFunction()">Try it</button> 
 

 
</body> 
 

 
</html>

plnkr http://plnkr.co/edit/VCGPPbWcock0PgC9wMWi?p=preview

+0

謝謝。代碼片段的一件事是,當您嘗試在第一個選項(hello.pdf)中上傳較大的文件(例如5 MB)時,第二個(check.txt)和第三個上傳選項(圖像.jpg),第一個文件需要更多時間才能讀取,因爲它的大小很大,但第二個和第三個文件佔用的時間更少。因此第二個文件首先被打印,第三個文件被打印第二個並且最後打印第一個文件。這是我長期面臨的問題。訂單必須保留。有多少時間需要讀取第一個文件,它應該先完整讀取,然後是第二個,然後是第三個。 –

+0

我試過一個例子,它的行爲方式如此。在完成當前循環(當它是大文件時)之前,它正在進入下一個循環。你有關於如何保存命令的建議嗎? –

+0

'FileReader'' load'事件異步返回結果。預期的訂單是什麼?用戶選擇文件的順序? _「這是我長期面臨的問題,訂單必須保留。」_是否在原始問題中描述了該要求? – guest271314