使用FormBuilder和formdata以角度上传文件

时间:2019-03-09 06:51:56

标签: angular multipartform-data form-data formbuilder

我想知道如何使用angular和form builder来上传文件,目前我只发现了使用formbuilder和单个文件的教程,例如File Upload In Angular?

我的问题是.ts文件,如何将文件附加到formbuilder中的字段?我见过formData()完成此操作,但无法让它们两者一起工作,非常感谢任何提示!

component.ts

 ngOnInit() {
   this.escolaridad_candidato =  this.fb.group({
      nivel_estudio: [, [Validators.required]],
      escuela: [, [Validators.required]],
      graduacion: [, [Validators.required]],
      certificado: [, [Validators.required]]  <--This is the file I need to append 
   });
 }

    onEstudiosChange(event) {
      const reader = new FileReader();
      if (event.target.files && event.target.files.length) {
        const [file] = event.target.files;
        reader.readAsDataURL(file);

        reader.onload = () => {
          this.exp_academica.patchValue({
            certificado: reader.result
        });
          // need to run CD since file load runs outside of zone
          this.cd.markForCheck();
        };
      }
    }

  // On Submit button
  this.myservice.post('myUrl', this.escolaridad_candidato.rawdata(), configOptions )

component.html

 <form [formGroup]="escolaridad_candidato" >
            <div class="col s6 center-align" >
              <p >Estudios</p>
              <div class="row">
                <div class="col s12">
                  <p >Degree</p>
                    <select class="browser-default" formControlName="nivel_estudio">
                      <option value="" disabled selected>----</option>
                      <option *ngFor="let nivel of listnivelEstudios" value="{{ nivel.id }}">
                        {{ nivel.nombre }}
                      </option>

                    </select>
                </div>
                <div class="col s12 center-align input-field">
                  <p >Escuela </p>
                  <input id="escuela" type="text" class="validate browser-default" formControlName="escuela"/>
                </div>
                <div class="col s12 input-field center-align">
                  <p >Año de graduación </p>
                  <input id="graduacion" type="text" class="validate browser-default" 
                   formControlName="graduacion" />
                </div>
              </div>
              <div class="row">
                <div class="col s12">
                  <p >Certificate </p>
                      <div class="file-field input-field">
                        <div class="btn" >
                          <span>Adjuntar archivo +</span>
                          <input type="file" formControlName="certificado" (change)="onEstudiosChange($event)">
                        </div>
                        <div class="file-path-wrapper">
                          <input class="file-path validate" type="text">
                        </div>
                      </div>
                </div>   
              </div>

            </div>
          </form>

2 个答案:

答案 0 :(得分:1)

我已经为Angular 7和小于7但大于2的任何版本指定了代码。

            formDataProductImagePost(endPoint, formData) {
               let headers = new Headers();
               let formDataFinal = new FormData();

               // The below for loop is for multiple file uploads. If you have only one file which needs to be uploaded then you don't need the loop.
               for (let j = 0; j < formData.length; j++) {
                    formDataFinal.append('file', formData[j]);
               }
               return this.http.post(this.profileApiUrl + endPoint, formDataFinal, {
                    headers: headers
               }).toPromise().then((response: any) => {
                    let image_id = JSON.parse(response._body)['response'];
                    // console.log(image_id);
                    return image_id;
               });
            }




/// This shall work on Angular 7. Let me know if you face any issues :).

 <form [formGroup]="myForm">
    <div class="form-group form-inline">
      <label class="btn btn-secondary btn-file">Browse
       <input name="file" type="file" (change)="onFileChange($event)">
       <input type="hidden" name="fileHidden" formControlName="file"/>        
       <!-- Validation Field -->
   </label>

    <p *ngIf="file" class="pl-4 align-middle mb-0">{{file.name}}</p>
  </div>
  <button type="button" class="btn btn-primary" (click)="finalUpload()">Upload</button>
</form>


// Angular Code
   public file: string = '';
   public fileN = new FormControl();

   ngOnInit() {
            let self = this;
            this.myForm = this.formBuilder.group({
                  fileN: [fileName, Validators.required]
            });

    }

   finalUpload() {
            this.uploadData().subscribe(data => {
                    console.log(data);
            });
    }

    uploadData():Observable<any> {
            let formData  = new FormData();
            let result = Object.assign({}, this.myForm.value);
            for (let o in result) {
                    formData.append(o, result[o])
            }
            return this.request.post<any>('http://localhost:8000/api/image', formData);
    }

    handleError(error: any) {
            return error;
            // console.log(error);
    }

    onFileChange($event) {
            this.file = $event.target.files[0]; // <--- File Object for future use.
            let file = $event.target.files[0]; // <--- File Object for future use.
            this.myForm.controls['fileN'].setValue(file ? file.name : ''); // <-- Set Value for Validation
    }

答案 1 :(得分:1)

很奇怪,关于如何执行此操作的文档很少。

答案相对简单:

html必须具有这样的输入

<input type="file" (change)="onFileChanged($event, i)">

使用fb,您可以使用以下方法提取表单的值: const myFormValue = this.myForm.value

在.ts文件中:

public onFileChanged(event: any) {
    if (event.target.files && event.target.files.length) {
    const file = event.target.files[0];
    this.certEscolar = file;
    }
  }

  submit() {
    const myFormValue = this.myForm.value

    const myFormData = new FormData();
    for ( let i = 0; i < myFormValue.length; i++ ) {         
      for ( let key of myFormValue) {
        myFormData.append(key, myFormValue[key]);
      }
    }

    this.http.post<any>(SOMEURL, myFormData, Config.api.multiContentOptions)
    .subscribe(response => {
       console.log("response from server!", response)
  }

我使用的标头是:

Config.ts

const MultipartHeaders: HttpHeaders = new HttpHeaders({
  Authorization: 'Token ' + token,
  Accept: 'application/json'
});



 let Config = {
  api: {
    baseURL: 'http://11.98.155.150/back/ws' //obviously fake
  options: { headers: jsonheaders },
  formatOptions: { headers : formDheaders },
  multiContentOptions: { headers : MultipartHeaders },
  }
};

如果有人要求我可以上载示例,那么使用formArrays和FormData会变得更加棘手。