Angular重复上传同一文件无响应及报错问题咨询
问题原因与解决方案
为什么会出现这两个问题?
重复上传同一文件无响应:
浏览器的input[type="file"]元素的change事件,只有当用户选中的文件和上一次选中的不一样时才会触发。如果选同一个文件,因为元素的value没有发生变化(依然是该文件的路径),所以事件不会被触发,自然uploadRenewals()不会执行。取消选择文件时报错:
当打开文件选择窗口后直接关闭(未选文件),event.target.files会是一个空的FileList,此时files.item(0)返回null,你后续尝试访问null.name就会抛出TypeError。
修复方案
我们需要针对这两个问题分别处理:
1. 解决重复上传同一文件的问题
在处理完文件上传逻辑后,手动重置input元素的value为空字符串。这样下次即使选同一个文件,元素的value从空变为文件路径,change事件就会正常触发。
首先在HTML中给input添加模板引用变量:
<div class="form-group"> <label for="file">Choose File</label> <input #fileInput type="file" id="file" (change)="uploadRenewals($event.target.files, fileInput)"> </div>
然后修改TypeScript代码,在处理完文件后重置input的value:
import { ViewChild, ElementRef } from '@angular/core'; // ... 其他组件代码 fileToUpload: File = null; @ViewChild('fileInput') fileInput: ElementRef; uploadRenewals(files: FileList, inputElement?: HTMLInputElement) { // 先处理未选文件的情况 if (!files || files.length === 0) { console.log('No file selected'); // 重置input值,避免影响下次选择 if (inputElement) inputElement.value = ''; return; } console.log('Uploading starts...', files); const formData: FormData = new FormData(); this.fileToUpload = files.item(0); formData.append('file', this.fileToUpload, this.fileToUpload.name); this._docService.uploadRenewals(formData) .pipe(take(1)) .subscribe((response: RenewalsResponse) => { console.log('Response is', response); // 上传成功后重置input,允许重复上传同一文件 if (inputElement) inputElement.value = ''; }, (error) => { console.log(error); // 上传失败也重置,避免后续操作异常 if (inputElement) inputElement.value = ''; }); }
2. 解决取消选择文件的报错问题
在uploadRenewals函数最开始,先判断files是否为空或者长度为0,如果是就直接返回,不执行后续的文件处理逻辑,这样就不会访问null.name了——上面的代码已经包含了这个判断逻辑。
额外优化建议
- 可以在模板中添加选中文件名称的展示,提升用户体验;
- 上传过程中可以添加loading状态,避免用户重复触发选择操作;
- 提前对文件类型、大小做校验,拦截不符合要求的文件,减少无效请求。
内容的提问来源于stack exchange,提问作者TheodoreTsg
相关产品推荐
相关产品推荐

