angular2 +文件上传进度指示器

时间:2018-10-01 16:08:37

标签: angular typescript file-upload multipartform-data

我有一个现有的表单上传组件,可以将文件上传到后端,这可以很好地工作,但是问题是我没有任何视觉指示器来指示有多少文件(即文件百分比)已上传到服务器。我相信这是我组件中缺少的急需的功能。目前,Please wait enter image description here来自app-loader.service.ts(截图),

是否可以通过上传的Please wait来修改% of file uploaded。我已经在网上使用progressbar看到了很多答案,但是我希望有一个对我来说有意义并针对自己的具体情况的解决方案。

form-upload.component.ts

import {  Component,  ViewChild, } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription';
import { Observer  } from 'rxjs/Observer';
import { HttpClient} from '@angular/common/http';
import { TranslateService } from '@ngx-translate/core';
import { FieldConfig } from '../../models/field-config.interface';
import { WebSocketService, DialogService } from '../../../../../../services/';
import { AppLoaderService } from '../../../../../../services/app-loader/app-loader.service';
import { Http } from '@angular/http';
import { MatSnackBar } from '@angular/material';


@Component({
  selector: 'app-form-upload',
  templateUrl: './form-upload.component.html',
  styleUrls: ['../dynamic-field/dynamic-field.css', 'form-upload.component.css'],
})
export class FormUploadComponent {
  @ViewChild('fileInput') fileInput;
  config: FieldConfig;
  group: FormGroup;
  fieldShow: string;
  public busy: Subscription[] = [];
  public sub: Subscription;
  public observer: Observer < any > ;
  public jobId: Number;
  public fileBrowser = true;
  public apiEndPoint = '/_upload?auth_token=' + this.ws.token;

  constructor(
    protected ws: WebSocketService, protected http: Http, private loader: AppLoaderService,
    private dialog:DialogService, public snackBar: MatSnackBar, public translate: TranslateService) {}

  upload(location = "/tmp/") {
    if(this.config.updater && this.config.parent ){
      this.config.updater(this, this.config.parent);
      return;
    }
  this.loader.open();

  const fileBrowser = this.fileInput.nativeElement;
  if (fileBrowser.files && fileBrowser.files[0]) {
    const formData: FormData = new FormData();
    formData.append('data', JSON.stringify({
      "method": "filesystem.put",
      "params": [location + '/' + fileBrowser.files[0].name, { "mode": "493" }]
    }));
    formData.append('file', fileBrowser.files[0]);

    this.http.post(this.apiEndPoint, formData).subscribe(
      (data) => {
        this.newMessage(location + '/' + fileBrowser.files[0].name);
        this.loader.close();
        this.snackBar.open("File upload complete.", 'close', { duration: 5000 });
      },
      (error) => {
        this.loader.close();
        this.dialog.errorReport(error.status, error.statusText, error._body);
      }
    );
  } else{
    this.loader.close();
  };
}
newMessage(message){
  if(this.config.message){
    this.config.message.newMessage(message);
  }

}
}

form-upload.component.html

 <div id="{{config.name}}" class="dynamic-field form-input" [formGroup]="group" [ngClass]="fieldShow" [class.has-tooltip]="config.tooltip" *ngIf="!config.isHidden">
  <div class="top">
    <label>{{ config.placeholder | translate }}</label>
    <tooltip *ngIf="config.tooltip" [message]="config.tooltip"></tooltip>
  </div>
  <div *ngIf="config.hideButton;else showButton">
      <mat-card-content>
          <input type="file" #fileInput accept="{{config.acceptedFiles}}" (change)="upload(config.fileLocation)" [formControlName]="config.name">
      </mat-card-content>
  </div>
  <ng-template #showButton>
      <mat-card-content>
          <input type="file" #fileInput accept="{{config.acceptedFiles}}" [formControlName]="config.name">
      </mat-card-content>
      <mat-card-actions class="buttons">
          <button mat-button type="button" (click)="upload(config.fileLocation)">Upload</button>
      </mat-card-actions>
      <mat-error *ngIf="config.hasErrors">{{config.errors}}</mat-error>
  </ng-template>
</div>

app-loader.service.ts

import { Injectable } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material';
import { Observable } from 'rxjs/Rx';
import { AppLoaderComponent } from './app-loader.component';
import { TranslateService } from '@ngx-translate/core';
import { T } from '../../translate-marker';

@Injectable()
export class AppLoaderService {
  dialogRef: MatDialogRef<AppLoaderComponent>;
  constructor(private dialog: MatDialog, private translate: TranslateService) { }

  public open(title: string = T('Please wait')): Observable<boolean> {
    this.translate.get(title).subscribe(t => {
      this.dialogRef = this.dialog.open(AppLoaderComponent, {disableClose: true});
      this.dialogRef.updateSize('200px', '200px');
      this.dialogRef.componentInstance.title = t;
    });
    return this.dialogRef.afterClosed();
  }

  public close() {
    this.dialogRef.close();
  }
}

1 个答案:

答案 0 :(得分:0)

https://malcoded.com/posts/angular-file-upload-component-with-express看了setValue(event){ this.currValue=event; } 的源代码之后,我想到了一个解决方案

如果有人感兴趣,这是差异。

src/app/upload/upload.service.ts