在 table angular 中仅从一行中选择文件
Choosing files from only one row in a table angular
我有一个 table,其中有一列包含选择文件的选项。我已经这样做了,但我的问题是,当我在特定行中选择文件时,所有行中的文件都会被选择。即使我删除它也会在所有行中被删除。我希望它只在一行中被选中或删除。
@angular 为 table 循环中的文件删除 ngFor
,如下所示。因为它一次又一次地循环相同的文件。
<div>* {{myFiles[i].name}}</div>
<button type="button" (click)="deleteRow(i)" class="btn btn-primary">X</button>
而不是这个
<div *ngFor="let file of myFiles; let i=index">
<div>* {{myFiles[i].name}}</div>
<button type="button" (click)="deleteRow(i)" class="btn btn-primary">X</button>
</div>
然后你像下面这样声明包含索引、文件、isUpload 的文件对象
myfiles: {index: string, file: any, isUpload: boolean}[] = [];
请查看 stackblitz 参考 url。
参考:https://stackblitz.com/edit/angular-ivy-jbgfgn?file=src%2Fapp%2Fapp.component.ts
When file in any row is selected, you have following same code in each row:
<div *ngFor="let file of myFiles; let i=index">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(i)" class="btn btn-primary">X</button>
</div>
每行打印所有文件。按某些行标识符存储文件(例如 name
)。
所以改变
myFiles: any[] = [];
至
myFiles: Record<string, File[]> = {};
getFileDetails()
函数应该接收 name
键:
getFileDetails (e, name) {
//console.log (e.target.files);
for (var i = 0; i < e.target.files.length; i++) {
this.myFiles[name] = this.myFiles[name] || [];
this.myFiles[name].push(e.target.files[i]);
}
console.log(this.myFiles)
}
uploadFiles()
:
uploadFiles() {
const frmData = new FormData();
Object.values(this.myFiles).flat().forEach(file => frmData.append("fileUpload", file));
}
deleteRow()
函数应该接收 name
键:
deleteRow(index: number, name: string) {
this.myFiles[name].splice(index,1);
// reset file input element
(document.querySelector(`#file_${name}`) as HTMLInputElement).files = undefined;
}
相关TDHTML:
<td>
<div>
<ng-container>
<input type="file" id="file" multiple
(change)="getFileDetails($event, list.name)">
</ng-container>
</div>
<div *ngFor="let file of myFiles[list.name]; let i=index">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(i, list.name)" class="btn btn-primary">X</button>
</div>
</td>
请注意,STACKBLITZ 可能尚不支持 Object.values(this.myFiles).flat()
,但任何现代浏览器都支持 should work。
您可以改用以下内容:
Object.values(this.myFiles).reduce((res, curr) => [
...res,
...curr
], []).forEach(file => frmData.append("fileUpload", file));
这里有一些修改,将维护具有实际记录(行)的文件列表。
首先修改listes
数据模型:
{
name: "A",
qty: 6,
value: 10,
files: [] // added files array here
},
接下来,修改getFileDetails
代码。您需要索引和目标。然后,按索引找到列表并将 target.files 推到该列表对象(行)上:
getFileDetails (index, e) {
//console.log (e.target.files);
for (var i = 0; i < e.target.files.length; i++) {
this.listes[index].files.push(e.target.files[i]);
}
console.log(this.myFiles)
}
更改delete
方法以从所选索引中删除所选文件。在这种情况下,我们需要两个索引,一个用于列表,一个用于文件。这些是在HTML(下)中创建的:
deleteRow(listIndex: number, fileIndex: number) {
this.listes[listIndex].files.splice(fileIndex,1);
}
最后 html 所需的更改很少,但与我上面提到的索引有关:
<tbody>
<tr *ngFor="let list of listes; index as listIndex">
<td>{{listIndex+1}}</td>
<td>{{list.name}}</td>
<td>{{list.qty}}</td>
<td>{{list.value}}</td>
<div style="overflow: auto;">
<td>
<div>
<ng-container>
<input type="file" multiple
(change)="getFileDetails(listIndex, $event)">
</ng-container>
</div>
<div *ngFor="let file of list.files; index as fileIndex">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(listIndex, fileIndex)" class="btn btn-primary">X</button>
</div>
</td>
</div>
</tr>
</tbody>
OP询问删除文件后清除文件输入。以下更改实现了这一点:
<input #fileInput type="file" multiple (change)="getFileDetails(listIndex, $event)">
</ng-container>
</div>
<div *ngFor="let file of list.files; index as fileIndex">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(listIndex, fileIndex); fileInput.value = ''" class="btn btn-primary">X</button>
工作闪电战可以在这里找到:https://stackblitz.com/edit/angular-ivy-gepzrz?file=src%2Fapp%2Fapp.component.html
我有一个 table,其中有一列包含选择文件的选项。我已经这样做了,但我的问题是,当我在特定行中选择文件时,所有行中的文件都会被选择。即使我删除它也会在所有行中被删除。我希望它只在一行中被选中或删除。
@angular 为 table 循环中的文件删除 ngFor
,如下所示。因为它一次又一次地循环相同的文件。
<div>* {{myFiles[i].name}}</div>
<button type="button" (click)="deleteRow(i)" class="btn btn-primary">X</button>
而不是这个
<div *ngFor="let file of myFiles; let i=index">
<div>* {{myFiles[i].name}}</div>
<button type="button" (click)="deleteRow(i)" class="btn btn-primary">X</button>
</div>
然后你像下面这样声明包含索引、文件、isUpload 的文件对象
myfiles: {index: string, file: any, isUpload: boolean}[] = [];
请查看 stackblitz 参考 url。
参考:https://stackblitz.com/edit/angular-ivy-jbgfgn?file=src%2Fapp%2Fapp.component.ts
When file in any row is selected, you have following same code in each row:
<div *ngFor="let file of myFiles; let i=index">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(i)" class="btn btn-primary">X</button>
</div>
每行打印所有文件。按某些行标识符存储文件(例如 name
)。
所以改变
myFiles: any[] = [];
至
myFiles: Record<string, File[]> = {};
getFileDetails()
函数应该接收 name
键:
getFileDetails (e, name) {
//console.log (e.target.files);
for (var i = 0; i < e.target.files.length; i++) {
this.myFiles[name] = this.myFiles[name] || [];
this.myFiles[name].push(e.target.files[i]);
}
console.log(this.myFiles)
}
uploadFiles()
:
uploadFiles() {
const frmData = new FormData();
Object.values(this.myFiles).flat().forEach(file => frmData.append("fileUpload", file));
}
deleteRow()
函数应该接收 name
键:
deleteRow(index: number, name: string) {
this.myFiles[name].splice(index,1);
// reset file input element
(document.querySelector(`#file_${name}`) as HTMLInputElement).files = undefined;
}
相关TDHTML:
<td>
<div>
<ng-container>
<input type="file" id="file" multiple
(change)="getFileDetails($event, list.name)">
</ng-container>
</div>
<div *ngFor="let file of myFiles[list.name]; let i=index">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(i, list.name)" class="btn btn-primary">X</button>
</div>
</td>
请注意,STACKBLITZ 可能尚不支持 Object.values(this.myFiles).flat()
,但任何现代浏览器都支持 should work。
您可以改用以下内容:
Object.values(this.myFiles).reduce((res, curr) => [
...res,
...curr
], []).forEach(file => frmData.append("fileUpload", file));
这里有一些修改,将维护具有实际记录(行)的文件列表。
首先修改listes
数据模型:
{
name: "A",
qty: 6,
value: 10,
files: [] // added files array here
},
接下来,修改getFileDetails
代码。您需要索引和目标。然后,按索引找到列表并将 target.files 推到该列表对象(行)上:
getFileDetails (index, e) {
//console.log (e.target.files);
for (var i = 0; i < e.target.files.length; i++) {
this.listes[index].files.push(e.target.files[i]);
}
console.log(this.myFiles)
}
更改delete
方法以从所选索引中删除所选文件。在这种情况下,我们需要两个索引,一个用于列表,一个用于文件。这些是在HTML(下)中创建的:
deleteRow(listIndex: number, fileIndex: number) {
this.listes[listIndex].files.splice(fileIndex,1);
}
最后 html 所需的更改很少,但与我上面提到的索引有关:
<tbody>
<tr *ngFor="let list of listes; index as listIndex">
<td>{{listIndex+1}}</td>
<td>{{list.name}}</td>
<td>{{list.qty}}</td>
<td>{{list.value}}</td>
<div style="overflow: auto;">
<td>
<div>
<ng-container>
<input type="file" multiple
(change)="getFileDetails(listIndex, $event)">
</ng-container>
</div>
<div *ngFor="let file of list.files; index as fileIndex">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(listIndex, fileIndex)" class="btn btn-primary">X</button>
</div>
</td>
</div>
</tr>
</tbody>
OP询问删除文件后清除文件输入。以下更改实现了这一点:
<input #fileInput type="file" multiple (change)="getFileDetails(listIndex, $event)">
</ng-container>
</div>
<div *ngFor="let file of list.files; index as fileIndex">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(listIndex, fileIndex); fileInput.value = ''" class="btn btn-primary">X</button>
工作闪电战可以在这里找到:https://stackblitz.com/edit/angular-ivy-gepzrz?file=src%2Fapp%2Fapp.component.html