首页 > 解决方案 > 如何以反应形式使用 Angular 6 选择文件和上传文件

问题描述

在这里我们需要添加测试用例,为此我们需要使用响应式表单中的 angular 6 使用输入类型文件上传文件。在上传文件并作为对 API 的响应发送时,我们在标题中得到响应为

test_template: "C:\fakepath\Copy of Task_angular_issue and change_logs.xlsx"

但在我们得到的回应中

{
  "Status": "Error",
  "Message": "Following parameter(s) are missing: test_script,test_template",
  "Result": []
}

可以,我知道如何上传文件

.html 文件

<div class="dashboard">
  <form class="example-form" [formGroup]="userForm" (ngSubmit)="addAutomationCase(this.login_type)">
    <div class="example-full-width" style="display: inline-block">
      <label>Template Upload</label>
      <input type="file" formControlName="test_template" accept=".xlsx,.xls" (change)="onSelectFile($event)" #fileInput>
    </div>

    <div class="dashboardFooter">
      <button type="submit" class="button btn-primary" mat-raised-button mat-button color="primary"> Save </button>
      <button type="reset" class="button btn-default" mat-raised-button mat-button color="default" [routerLink]="['/auth/admin/Manage_Automation']"> Cancel </button>
    </div>
  </form>

</div>

ts文件

import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import {FormControl, FormGroupDirective,FormGroup, NgForm, Validators, FormBuilder} from '@angular/forms';
import {ErrorStateMatcher} from '@angular/material/core';

import {ActivatedRoute, Router} from "@angular/router";

import { AutomationCaseServiceProvider } from "../../../services/automationCase-service";
import { AuthServiceProvider } from "../../../services/auth-service";
import {MatSnackBar} from '@angular/material';
import { FilterTableComponent } from '../../../tables/filter-table/filter-table.component';

export class MyErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    const isSubmitted = form && form.submitted;
    return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
  }
}

@Component({
  selector: 'app-add-automation',
  templateUrl: './add-automation.component.html',
  styleUrls: ['./add-automation.component.scss'],
  providers: [ AutomationCaseServiceProvider, AuthServiceProvider]
})
export class AddAutomationComponent implements OnInit {


  account: { test_template: string } = {
    test_template: ''
  };

  userForm: FormGroup;

  constructor(private formBuilder: FormBuilder,
    private router: Router,
    public authService: AuthServiceProvider,
    public automationCaseService: AutomationCaseServiceProvider,
    public snackBar: MatSnackBar) {

  }

  ngOnInit() {

   **Initialize the Form Here**

    this.buildForm();

  }


  buildForm(): void {



    this.userForm = this.formBuilder.group({
        'test_template': ['', Validators.required]
      })
      console.log(this.userForm);
  };

  addAutomationCase() {
        if (!this.userForm.valid) {
          return;
        }
        else {
            this.automationCaseService.addautomationCase(this.userForm.value).subscribe(
              (resp) => {
                let UserData = JSON.stringify(resp);
                let data = JSON.parse(UserData);

                console.log(data.Message);
                if(data.Status == "Error"){
                  this.snackBar.open(data.Message,'Close', {
                    duration: 2000
                  });
                }

                else if(data.Status == "Success"){
                  this.snackBar.open(data.Message,'Close', {
                    duration: 2000
                  });
                this.router.navigate(['/auth/admin/Manage_Automation']);
                }
          });
      }
  }

  onSelectFile(event) {
    // console.log(JSON.stringify(event.target));
    // if (event.target && event.target[0]) {
    //   var reader = new FileReader();
    //   reader.readAsDataURL(event.target[0]); 
    //   // read file as data url
    //   alert(event.target.files[0]);
    // }
    let fileList: FileList = event.target.files;
    if(fileList.length > 0){
      var reader = new FileReader();
      reader.readAsDataURL(event.target.files[0]);
      console.log(event.target.files[0].name);
    }
    this.test_template = event.target.files[0].name;



          // need to run CD since file load runs outside of zone
          //this.cd.markForCheck()
  }

  onSelectscript(event) {
    if (event.target.files && event.target.files[0]) {
      var reader = new FileReader();
      reader.readAsDataURL(event.target.files[0]); // read file as data url
    }
  }

  matcher = new MyErrorStateMatcher();

}

标签: angularangular-reactive-formsangular6-json-schema-form

解决方案


您可以通过从@rxweb/reactive-form-validators 导入 RxFormBuilder 来以角度反应形式上传文件,创建其对象并使用 toFormData() 方法将 json 数据转换为 formData,这里我在服务器端供您参考,它将文件对象传递给服务器。在 html 中添加 [writeFile]="true" 时,不需要调用 onSelectFile($event)

组件.ts:

export class AddAutomationComponent implements OnInit {
   api:string = 'api/User'

  account: { test_template: string } = {
    test_template: ''
  };

  userForm: RxFormGroup;

  constructor(private formBuilder: RxFormBuilder,private http: HttpClient ) {

  }

  ngOnInit() {
    this.buildForm();
  }


  buildForm(): void {
    this.userForm = <RxFormGroup>this.formBuilder.group({
        'test_template': ['', Validators.required]
      })
     let formdata = this.userForm.toFormData()
       this.http.post(this.api, formdata); // This is fake uri, This is just for your reference.
  };
}

在component.html中:

<div class="dashboard">
  <form class="example-form" [formGroup]="userForm" (ngSubmit)="addAutomationCase(this.login_type)">
    <div class="example-full-width" style="display: inline-block">
      <label>Template Upload</label>
      <input type="file" formControlName="test_template" accept=".xlsx,.xls" [writeFile]="true">
    </div>

    <div class="dashboardFooter">
      <button type="submit" class="button btn-primary" color="primary"> Save </button>
      <button type="reset" class="button btn-default" color="default"> Cancel </button>
    </div>
  </form>

</div>

堆栈闪电战


推荐阅读