*ngFor 循环中的多个输入文件问题

Problem with multiple input file in *ngFor loop

我在 *ngFor 循环中定位正确的输入时遇到问题。当我使用第一个输入(Certificat dimmatriculation)添加图像时,我显示一个占位符图像和一个删除按钮以重置输入(有效)但它显示在 div.

我只想定位我添加实际图像的输入。我有一个 ViewChild,但我似乎无法让它工作。

See image here

这是代码:

<div class="files">
     <div class="single-file" *ngFor="let file of files">
          <h5>{{file.title}}</h5>
          <input type="file" name="file" id="{{file.slug}}" class="inputfile" #fileInput (change)="addFile(fileInput.files[0])" />
          <label for="{{file.slug}}" *ngIf="!hasFile || isDeleted">
          <img class="d-none d-xl-inline-block" src="assets/images/addImg.png" alt="">
          Ajouter votre photo
          <img class="d-block d-xl-none" src="assets/images/addImg_big.png" alt="">
     </label>
     <div class="placeholder" *ngIf="hasFile && !isDeleted">
          <img [src]="imageUrl" />
      </div>
      <div class="deleteImg" *ngIf="hasFile && !isDeleted" (click)="deleteFile()">
          <div class="btn btn-outline"><img src="assets/images/delete-x-icon.png" alt="Supprimer">Supprimer</div>
          </div>
     </div>
</div>

并在 .ts 中:

我声明了我所有的变量

file: File;
imageUrl: string | ArrayBuffer = '../app/assets/images/imgAdded.png';
hasFile = false;
isDeleted = false;

@ViewChild('fileInput', { static: false }) myFileInput: ElementRef;

files: any = [{
    'title': 'Certificat dimmatriculation',
    'slug': 'immatriculation',
    'input': '#fileInput1'
}, {
    'title': 'Preuve dassurance',
    'slug': 'insurance',
    'input': '#fileInput2'
}];

addFile(file: File) {
    if (file) {
        this.hasFile = !this.hasFile;
        // this.fileName = file.name;
        this.file = file;

        const reader = new FileReader();
        reader.readAsDataURL(file);

        reader.onload = event => {
            this.imageUrl = this.imageUrl;
            // this.imageUrl = reader.result;
        };
    }
}

deleteFile() {
    this.isDeleted = !this.isDeleted;
    this.myFileInput.nativeElement.value = '';
}

您目前的问题是您正试图通过使用组件级属性来管理单个 file 属性。我建议使用文件属性来存储上传的图像数据。然后所有操作都限定在 file 个实例中。

出于演示的目的,我已经简化了您的代码示例,并帮助您了解我采用的方法。

我在名为 imageUrl 的单个文件上使用 属性 来存储上传的图像数据 url。此 属性 中存在一个值表示已上传图像。 属性 删除图片时清空

component.html

<div *ngFor="let file of files">
  <h5>{{file.title}}</h5>    
  <label *ngIf="!file.imageUrl">
    <input type="file" (change)="addFile(file, $event)" />
    Ajouter votre photo
  </label>  
  <ng-container *ngIf="file.imageUrl">
    <img [src]="file.imageUrl" />
    <button (click)="deleteFile(file)">Supprimer</button>
  </ng-container>
</div>

所有操作现在都在单个 file 对象上执行,并且需要传递给事件处理程序。您也可以使用数组索引而不是对象引用。

file 实例和从输入上传的文件之间也可能存在一些混淆。如果可能,我建议将 filesfile 变量重命名为其他变量,并在处理文件输入时保留 file

component.ts

addFile(file, event) {
  const uploaded = event.target.files[0];
  if (!uploaded) {
    return;
  }

  const reader = new FileReader();
  reader.onload = () => {
    file.imageUrl = reader.result;
  };

  reader.readAsDataURL(uploaded);
}

deleteFile(file) {
  file.imageUrl = '';
}

演示:https://stackblitz.com/edit/angular-bcgwrq