Angular 8 ngFor上传文件时index始终为0,代码哪里出错?
嘿,我一眼就发现问题所在啦,这就给你拆解清楚:
核心问题分析
你遇到的uploadFile里index始终为0的情况,主要是两个原因导致的:
- NGFor语法错误:你用逗号分隔了循环表达式和index变量,Angular的
*ngFor要求用分号来分隔不同的循环参数,不过这个不是直接导致index异常的原因,但得先修正。 - 重复的DOM ID + 错误的DOM定位:所有文件输入框的id都是
file,而且你的browseFile()方法每次只会获取页面上第一个id为file的元素。不管你点哪一行的"Choose file"按钮,触发的都是第一行的input点击事件,自然uploadFile里拿到的index永远是0。
而删除按钮能正常工作,是因为它的(click)="onDeleteEvidence(i)"是直接绑定到当前循环的index,每个按钮的点击事件都对应自己行的i,所以索引没问题。
修复方案(两种写法)
写法1:修正DOM ID定位
先把语法和DOM定位的问题解决:
- 修正
*ngFor的语法:
<div class="row" *ngFor="let evidence of evidences; index as i">
- 给每个文件输入框生成唯一ID:
<input type='file' id="file-{{i}}" style="display:none" (change)="uploadFile(i, $event)">
- 修改
browseFile方法,让它能定位到当前行的输入框:
<button (click)="browseFile(i)" style="float: left; border: none">Choose file</button>
browseFile(index: number) { document.getElementById(`file-${index}`).click(); }
- 最后在对应行添加文件名显示:
<span *ngIf="evidence?.file">{{evidence.file.name}}</span>
写法2:更优雅的Angular风格(推荐)
其实完全不用手动操作DOM,用Angular的模板引用变量就能搞定,还能删掉多余的browseFile方法:
<div class="row" *ngFor="let evidence of evidences; index as i"> <div class="col"> {{i}} <!-- 用模板引用变量#fileInput标记输入框 --> <input type='file' #fileInput style="display:none" (change)="uploadFile(i, $event)"> <!-- 直接调用变量的click方法触发选择文件 --> <button (click)="fileInput.click()" style="float: left; border: none">Choose file</button> <!-- 上传后显示文件名 --> <span *ngIf="evidence?.file" style="margin-left: 8px;">{{evidence.file.name}}</span> </div> <div class="col"> </div> <div class="col"> <button pButton type="button" icon="pi pi-times" class="ui-button-danger action remove" (click)="onDeleteEvidence(i)"></button> </div> </div>
这种写法完全符合Angular的组件化思路,避免了手动操作DOM的潜在问题,代码也更简洁。
内容的提问来源于stack exchange,提问作者Matexon
相关产品推荐
相关产品推荐

