如何在Angular 4中上传相同的文件

10
我已经成功地上传了一个文件,但现在的问题是它不允许我再次上传同一个文件。这是我的代码:

代码内容

 <input type="file" (change)="onFileChange($event)" name="fileUploaded" value="Choose a File" accept=".xlsx, .xlsm">

我发现onFileChange($event)不会触发,因为我使用的监听器是(change),而且我没有更改上传的文件。我该怎么办才能解决这个问题?谢谢
编辑:为了让你理解我为什么要这样做,我想上传一个Excel文件,然后在页面上显示它的内容。但当我上传一个Excel文件,然后使用MS Excel编辑其中的数据并保存并重新上传时,新的编辑不会显示在页面上。页面仍然显示旧数据。
这是我的事件处理程序代码:
data: AOA = [ [], [] ];
reader: FileReader = new FileReader();
onFileChange(evt: any) {
        /* wire up file reader */
        console.log("G");
        const target: DataTransfer = <DataTransfer>(evt.target);
        this.reader.onload = (e: any) => {
            /* read workbook */
            this.data = [ [], [] ];
            console.log(target.types);
            const bstr: string  = e.target.result;
            const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
            /* grab first sheet */
            const wsname: string = wb.SheetNames[0];
            const ws: XLSX.WorkSheet = wb.Sheets[wsname];
            /* save data */
            this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
        }
            this.reader.readAsBinaryString(target.files[0]);
    }

在你的“onFileChange”函数结束时清除输入。 - Carsten
7个回答

22
你可以引用并清除你的输入:

模板

<input #myFileInput type="file"/>

脚本

@ViewChild('myFileInput') myFileInput;

onFileChange(event) { 
  this.myFileInput.nativeElement.value = '';
}

只需将它插入您自己的文件中。您可以将myFileInput命名为任何您想要的名称。 - Carsten
仍然无法工作。我相信原因是我正在尝试上传相同的文件,但onFileChange($event)不会触发,因为监听器是(change),而我正在上传相同的文件,尽管内容不同。 - thegreathypocrite
这就是为什么要清除输入,以便它不会知道先前的文件是相同的。 - Carsten
我认为解决这个问题的方法是用其他东西替换(change)监听器。 我已经阅读了这篇文章:“……通常情况下,如果您选择一个文件,关闭输入,然后在下一次打开它时再次选择相同的文件,则浏览器不会触发更改事件。这是有道理的,因为从技术上讲,没有什么改变……”来自https://github.com/dtruel/angular-file-input/tree/master 但问题是要用什么来替换(change)监听器。 - thegreathypocrite
1
抱歉,应该是:this.myFileInput.nativeElement.value = '''; - Carsten
显示剩余3条评论

8

这种情况有点像缓存。因此,在上传文件之前,请确保清理缓存,您可以将值设置为空,然后上传文件。

<input type ="file" #fileUpload style="visibility: hidden;" (change)="uploadResume($event)"> 
<button (click)="fileUpload.value='';fileUpload.click();">Upload</button>

4
你可以引用然后清除你的输入:
模板
<input (click)="clearFile()" #myFileInput type="file"/>

脚本

@ViewChild('myFileInput') myFileInput;

clearFile(event) { 
  this.myFileInput.nativeElement.value = '';
}

2

只需尝试 (onclick)="this.value = null"

在您的HTML页面中添加onclick方法以删除先前的值,以便用户可以再次选择相同的文件。


注:Original Answer翻译成“最初的回答”未被包含在需要翻译的内容中,因此不进行翻译。

稍微解释一下可能会改善这个答案。 - A Jar of Clay

0

你也可以尝试这种方式。我曾经成功上传过同一张图片两次。

app.component.html

<p>App image</p>
<input matInput [disabled]="true" />
<input #imageInput accept="image/*" (change)="selectImageFile(imageInput)" type="file" id="file" (click)="imageInput.value='';">

app.component.ts

selectImageFile(imageInput: any) {
let file: File = imageInput.files[0];
const reader = new FileReader();
reader.addEventListener('load', (event: any) => {
  this.selectedFile = new ImageSnippet(event.target.result, file);
  this.applicationService.imageUpload(this.selectedFile.file).subscribe(
    (res) => {
      this.isImageSubmitted = true;
      this.selectedImagename = res.data;
    },
    (err) => {
      this.isImageSubmitted = false;
    }
  );
});
reader.readAsDataURL(file);

}


这是最正确的答案,如果1-我们不需要任何外部按钮,以及2-只有一个输入字段具有(单击)事件来清除文件和(更改)事件来上传(也可以使用输入事件代替更改)。 这始终确保(单击)事件将在(更改)事件之前清除文件。 P.S. - 仅为明确起见,我们不需要第一个<input matInput [disabled] =“true”/>。并请编辑并删除selectImageFIle()函数中的所有代码,这将是一个完美的答案供投票支持。 :) - Jagdeep Singh

0
你可以像下面这样实现它
<input type="file" #fileInput style="display: none"  accept=".csv"  (change)="OnFileSelected($event)" (click)="$event.target.value=null"/>

0
最简单的方法是在点击时将输入(文件类型)的值设置为null。
onclick="this.value = null"

就像你的输入应该是一样的

<input type="file" (change)="onFileChange($event)" name="fileUploaded" value="Choose a File" accept=".xlsx, .xlsm" onclick="this.value = null">

答案已经在这里给出了


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接