angular - Özel uploadHandler kullanıldığında PrimeNG Dosya Yükleme İlerlemesi güncellenmiyor


PrimeNG Dosya Yükleme Bileşenini kullanmaya çalışıyorum

Ama bir API'ye yüklüyorum, bu yüzden şöyle bir özel uploadHandler kullanıyorum:

<p-fileUpload #fileUpload name="fileUpload" 
              (uploadHandler)="uploadHandler($event)" customUpload="true" fileLimit="5"
              multiple="multiple" accept="image/*" maxFileSize="1000000">
</p-fileUpload>

Aşağıdakileri çağıran bir component.ts ile:

uploadedFiles: any[] = [];
@ViewChild('fileUpload') fileUpload: any;

constructor(private wpService: WordpressService, private cd: ChangeDetectorRef) {}

async uploadHandler(event) {
    console.log(this.fileUpload)
    this.fileUpload.disable = false;
    this.fileUpload.progress = 5;
    this.fileUpload.onProgress.emit({progress: this.fileUpload.progress});
    this.cd.detectChanges();
    this.uploadedFiles = [];

    const perFilePercent = 95 / event.files.length;
    this.fileUpload.disable = true;
    for (const f of event.files) {
        await this.wpService.uploadFile(f).then(response  => {
            const thisFile = f;
            thisFile.id = response.id;
            thisFile.url = response.source_url;
            this.fileUpload.progress += perFilePercent;
            this.fileUpload.onProgress.emit({progress: this.fileUpload.progress});
            this.cd.detectChanges();
            this.uploadedFiles.push(thisFile);
    });
    }

    this.fileUpload.files = [];
    this.cd.detectChanges();
}

Sorun şu ki, this.fileUpload.progress += perFilePercent; VE this.fileUpload.onProgress.emit({progress: this.fileUpload.progress}); yaparak ilerlemenin manuel olarak değişmesini sağlamaya çalışmama rağmen, hiçbir şey olmuyor.

Garip olan şu ki, eğer ardından bir ilerleme çubuğu bileşenini this.fileUpload.progress değerine bağlarsam, güncellenecektir. Örneğin:

<p-progressBar [value]="fileUpload.progress" [showValue]="false"></p-progressBar>

Davranışın beklendiği gibi çalışmasına neden olurken, aslında dosya yükleme bileşeni içindeki ilerleme çubuğu durur ve ilk çağrıyı geçtikten sonra güncellenmez.

Bu davranışın bir videosu: https://bitz.rocks/ftp/3HJvut0t6p.mp4

ViewChild değerlerini ayarlayan satırlarda veya event emitter'da bir şeyleri yanlış yaptığımı hissediyorum ama neyin yanlış olduğunu ya da ne yapmam gerektiğini çözemedim.

Cevap #1

Biliyorum, eski bir gönderi, ama bugün ben de benzer bir görev yapıyordum ve onu böyle çözdüm.

/*before constructor*/

totalPercent = 0;
percentDone: number;
@ViewChild('primeFileUpload') primeFileUpload: FileUpload;
private percentDonePerFile: number;

async fileUpload($event) {
    if ($event && $event.files) {
      this.totalPercent = $event.files.length * 100;
      this.percentDone = 0;
      console.log('uploading..');
      let sub;
      let i = 1;
      for (const file of $event.files) {
        const path = '/my/super/path';
        sub = this.docService.percentSub.subscribe(perc => {
          this.percentDonePerFile = perc;
          this.percentDone = (i - 1) * 100 + this.percentDonePerFile;
          console.log('emitting: ' + (this.percentDone / this.totalPercent * 100));
          this.primeFileUpload.onProgress.emit(this.round(this.percentDone / this.totalPercent * 100));
        });
        const dummyEvent = {srcElement: {files: [file]}};
        await this.docService.uploadFile(dummyEvent, path);
        this.percentDone = i * 100;
        this.primeFileUpload.onProgress.emit(this.round(this.percentDone / this.totalPercent * 100));
        console.log('emitting: ' + (this.percentDone / this.totalPercent * 100));
        sub.unsubscribe();
        i++;
      }
    }
  }

  progressReport($event: any) {
    this.primeFileUpload.progress = $event;
  }

html dosyam şu kadar basit:

      <p-fileUpload customUpload="true" #primeFileUpload
                multiple="true" (onProgress)="progressReport($event)"
                accept="image/*" maxFileSize="2000000" (uploadHandler)="fileUpload($event)"></p-fileUpload>

Birine yardım edebilir! Harika bir gün geçir.

Cevap #2

Bu benim için işe yaradı, çünkü API değişti.

HTML

<div class="card flex justify-content-center">
    <p-toast />
    <p-fileUpload #fileUploaderForm name="demo[]" [multiple]="false" customUpload="true"
        (uploadHandler)="handleFileUpload($event, fileUploaderForm)"
        (onProgress)="onProgress($event, fileUploaderForm)">
        <ng-template pTemplate="content">
            <ul *ngIf="uploadedFiles.length">
                <li *ngFor="let file of uploadedFiles">
                    {{ file.name }} - {{ file.size }} bytes
                </li>
            </ul>
        </ng-template>
    </p-fileUpload>
</div>

TS/JS

uploadedFiles: any[] = [];

  constructor(private messageService: MessageService) { }

  async handleFileUpload(event: FileUploadHandlerEvent, fileUploadForm: FileUpload) {
    console.log('handle file upload', event, fileUploadForm);

    try {
      const result = await uploadData({
        path: `upload/${event.files[0].name}`,
        data: event.files[0],
        options: {

          onProgress: (progress) => {
            const progressPct = Math.round(progress.transferredBytes / progress.totalBytes! * 100)
            fileUploadForm.onProgress.emit({
              originalEvent: undefined!,
              progress: progressPct
            });
          }
        }
      }).result;
      this.messageService.add({ severity: 'success', summary: 'Success', detail: 'File Uploaded', life: 3000 });
      fileUploadForm.clear();
      this.uploadedFiles.push(event.files[0]);

    } catch (error) {
      console.log('Error : ', error);
    }
  }
  onProgress(event: FileProgressEvent, fileUploadForm: FileUpload) {
    fileUploadForm.progress = event.progress;
  }