Многократная загрузка угловых файлов без дубликатов

#angular #file-upload

#angular #загрузка файла

Вопрос:

Я новичок в angular и изучаю, как загружать несколько файлов на свой сервер. Итак, что я смог сделать, так это то, что я могу загружать файлы, отображать счетчик, а затем отображать эти файлы под кнопкой загрузки.

component.html :

  <div fxFlex="50" class="mb-24" *ngIf="show">
        <button mat-raised-button color="primary" (click)="hiddenfileinput.click()" fxFlex="50">
           <mat-icon>cloud</mat-icon>
           load documents
        </button>
     <input type="file" id="fileUpload" name="fileUpload" multiple (change)="onUpload($event)"   #hiddenfileinput style="display:none;"/>
 </div>
  <div *ngIf="!isLoading ; else loadBlock">
          <div *ngFor="let file of viewFiles">
               <span><mat-icon>attachment</mat-icon>{{file}}</span>  
          </div> 
                                    
  </div>
  <ng-template #loadBlock>
        <mat-spinner [diameter]="20"></mat-spinner>
  </ng-template>
  

Функция загрузки Component.ts :

   viewFiles : string[]= [];
  isLoading = false; 
  files: FormData = new FormData(); 

onUpload(event)
  {
    this.isLoading = true;
    const fdata = event.target.files;


    for (let i = 0; i < fdata.length; i  ) 
    {
       this.files.append('file[]', fdata[i], fdata[i].name);
    }
     for (var pair of this.files.values()) 
    {
     this.viewFiles.push(pair.name);
    }
 setTimeout(() => {
      this.isLoading = false
    },2500)
}
  

Итак, вот проблема: что, если пользователь нажимает кнопку загрузки, загружает 1 файл, а затем снова нажимает на кнопку и загружает тот же файл и 3 других файла, тогда у меня будет дублированный файл в списке, как я могу проверить, существует ли файл уже? или избегать дублирования файлов?

Спасибо!

Редактировать

Найдено рабочее решение :

 this.isLoading = true;
    const fdata = event.target.files;

    for (let i = 0; i < fdata.length; i  ) 
    {
      for (var pair of this.files.values()) 
      {
       if(pair.name == fdata[i].name)
       {
         this.fileExists = true;
       }
      }

   if (!this.fileExists) {
     this.files.append('file[]', fdata[i], fdata[i].name);
     this.viewFiles.push(fdata[i].name);
   }
  

Ответ №1:

Вы всегда можете проверить наличие дубликатов на основе имени файла, прежде чем добавлять файл в this.files :

 for (let i = 0; i < fdata.length; i  ) 
{
   // check if fdata[i].name already exists in this.files
   const fileExists = false;
   for (var pair of this.files.values()) { 
     if (pair.name == fdata[i].name) { 
       this.fileExists = true; 
     } 
   } 
   if (!fileExists) {
     this.files.append('file[]', fdata[i], fdata[i].name);
   }
}
  

Комментарии:

1. Не работает, я получаю эту ошибку «ОШИБКА TypeError: this. files.values(…).find не является функцией »

2. это. files.values возвращает объект итератора, поэтому мы не можем выполнить выборку через него.

3. Я не тестировал код, он ближе к псевдокоду, чем фактический код. но вам нужно будет найти способ использовать find on this.files . попробуйте this.files.find(... без values()

4. Я нашел это решение this.isLoading = true; const fdata = event.target.files; for (let i = 0; i < fdata.length; i ) { for (var pair of this.files.values()) { if(pair.name == fdata[i].name) { this.fileExists = true; } } if (!this.fileExists) { this.files.append('file[]', fdata[i], fdata[i].name); this.viewFiles.push(fdata[i].name); }

5. @ilyasDH Я соответствующим образом скорректировал свой ответ

Ответ №2:

Вы также можете выполнить повторную проверку измененного времени для сравнения, если файл тот же

   /**
   * values has changed
   */
  public onInputChange(event: Event): void {
    const newFiles: FileList = (<HTMLInputElement>event.target).files;
    this.value = this.value || [];

    // add only unique files
    for (const file of Array.from(newFiles)) {
      if (this.isSameNameAndModified(file)) {
        this.value.push(file);
      }
    }
    this.onChanged(this.value);
  }

  /**
   * unique based on name and modified
   */
  private isSameNameAndModified(file: File): boolean {
    for (const { name, lastModified } of this.value) {
      if (file.name === name amp;amp; file.lastModified === lastModified) {
        return false;
      }
    }
    return true;
  }