首页 > 解决方案 > Angular 在尝试使用反应式表单动态创建表单字段时自动发出发布请求

问题描述

我正在尝试创建一个角度反应表单,用户可以通过按下添加(+)按钮在一个表单中输入多个日期,这将动态创建表单字段以获取日期类型的输入。我希望用户能够添加任意数量的日期,并且在添加所有日期后,用户将按下提交按钮并将数据发送到后端。但是在我的代码中,每当我按下添加 (+) 按钮来创建一个新的表单字段时,它都会自动从 sample.component.ts 文件中调用 onSubmit() 函数,而不是仅仅调用 addReportingDate() 函数,这会生成一个不需要的帖子请求。我该如何解决这个问题?

示例.component.html

<h2 mat-dialog-title>
  KPI
</h2>
<div mat-dialog-content class="create-department-form">
  <form
    [formGroup]="kpiForm"
    class="department-form"
    (ngSubmit)="onSubmit()"
  >
    <mat-form-field>
      <mat-label>KPI Name</mat-label>
      <label>
        <input formControlName="name" matInput/>
      </label>
    </mat-form-field>
    <mat-form-field>
      <mat-label>KPI Weight</mat-label>
      <label>
        <input type="number" formControlName="weight" matInput/>
      </label>
    </mat-form-field>
    <mat-form-field>
      <mat-label>Select Department Name</mat-label>
      <input type="text"
              placeholder="Pick one"
              aria-label=""
              matInput
              formControlName="departmentId"
              [matAutocomplete]="auto1"
              (keyup)="onKey($event)">
      <mat-autocomplete #auto1="matAutocomplete">
        <mat-option *ngFor="let department of departments" [value]="department.id">
          {{department.id + ' - ' + department.name}}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
    <mat-form-field>
      <mat-label>Select Employee List</mat-label>
      <input type="text"
              placeholder="Pick one"
              aria-label=""
              matInput
              formControlName="employeeId"
              [matAutocomplete]="auto2"
              (keyup)="onKey($event)">
      <mat-autocomplete #auto2="matAutocomplete">
        <mat-option *ngFor="let employee of employees" [value]="employee.id">
          {{employee.id + ' - ' + employee.name}}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
    <mat-form-field>
      <mat-label>Select Goal KPI Name</mat-label>
      <input type="text"
              placeholder="Pick one"
              aria-label=""
              matInput
              formControlName="goalKpiId"
              [matAutocomplete]="auto"
              (keyup)="onKey($event)">
      <mat-autocomplete #auto="matAutocomplete">
        <mat-option *ngFor="let goalKpi of goalKpis" (click)="updateGoalKpiSpaceStatus(goalKpi)" [value]="goalKpi.id">
          {{goalKpi.id + ' - ' +goalKpi.name}}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
    <span *ngIf="selectedGoalKpiWeight">
      <span class="status">Selected Goal KPI Weight: {{selectedGoalKpiWeight ? selectedGoalKpiWeight : 'N/A'}}</span>
      <span class="status">Total Weight Taken: {{selectedGoalKpiTakenWeight ? selectedGoalKpiTakenWeight : 'N/A'}}</span>
      <span class="status">Remaining Weight: {{selectedGoalKpiRemainingWeight ? selectedGoalKpiRemainingWeight : 'N/A'}}</span>
    </span>
    <mat-form-field>
      <mat-label>Add Reporting Date(s)</mat-label>
      <div formArrayName="reportingDates">
        <div *ngFor="let date of reportingDates.controls; let dateIndex=index" [formGroupName]="dateIndex">
          <input type="date" formControlName="date" matInput/>
          <button id="deleteButton" (click)="deleteReportingDate(dateIndex);" mat-mini-fab color="warn" aria-label="Delete reporting date.">
            <mat-icon>delete</mat-icon>
          </button>
        </div>
        <button id="addButton" (click)="addReportingDate()" mat-mini-fab color="primary" aria-label="Add another reporting date.">
          <mat-icon>add</mat-icon>
        </button>
      </div>
    </mat-form-field>
  </form>
</div>

<div mat-dialog-actions>
  <button
    (click)="onSubmit()"
    type="submit"
    mat-raised-button
    color="primary"
    [disabled]="!kpiForm.valid"
  >
    Submit
  </button>
  <button mat-raised-button color="warn" type="button" (click)="onNoClick()">
    Cancel
  </button>
</div>

sample.component.ts 文件

@Component({
  selector: 'app-add-edit-kpi-dialog',
  templateUrl: './add-edit-kpi-dialog.component.html',
  styleUrls: ['./add-edit-kpi-dialog.component.scss']
})
export class AddEditKpiDialogComponent implements OnInit {

  kpiForm: FormGroup;
  goalKpis: IGoalKpi[];
  departments: IDepartmentList[];
  employees: IEmployeeList[];
  value: string;
  selectedGoalKpiWeight: number;
  selectedGoalKpiTakenWeight = 0;
  selectedGoalKpiRemainingWeight = 0;

  constructor(
    private dialogRef: MatDialogRef<AddEditKpiDialogComponent>,
    private formBuilder: FormBuilder,
    private dialog: MatDialog,
    private goalKpiService: GoalKpiService,
    private kpiService: KpiService,
    private departmentService: DepartmentService,
    private employeeService: EmployeeService,
    private loaderService: NgxUiLoaderService,
    private alertService: AlertService,
    @Inject(MAT_DIALOG_DATA) public data: {
      isEdit: boolean,
      kpiData: IKpi
    }
  ) {
    this.kpiForm = this.formBuilder.group({
      name: ['', Validators.required],
      weight: ['', Validators.required],
      goalKpiId: ['', Validators.required],
      departmentId: ['', Validators.required],
      employeeId: ['', Validators.required],
      reportingDates: this.formBuilder.array([this.formBuilder.group({date: ''})]),
    });
  }

  ngOnInit(): void {
    this.loadAllRequiredData();

    if (this.data.isEdit) {
      this.populateForm();
    }
  }

  get reportingDates() {
    return this.kpiForm.get('reportingDates') as FormArray;
  }

  addReportingDate() {
    this.reportingDates.push(this.formBuilder.group({date: ''}));
  }

  deleteReportingDate(index) {
    this.reportingDates.removeAt(index);
  }

  populateForm() {
    this.kpiForm.controls.name.setValue(this.data.kpiData.name);
    this.kpiForm.controls.weight.setValue(this.data.kpiData.weight);
    this.kpiForm.controls.goalKpiId.setValue(this.data.kpiData.goalKpiName);
    this.kpiForm.controls.employeeId.setValue(this.data.kpiData.employeeName);
    this.kpiForm.controls.departmentId.setValue(this.data.kpiData.departmentName);
  }

  loadAllRequiredData() {
    this.loaderService.start();
    forkJoin([
      this.departmentService.getDepartmentByName(''),
      this.employeeService.getEmployeeByName(''),
      this.goalKpiService.getGoalKpiByName(''),
    ]).subscribe(response => {
      this.departments = response[0].data;
      this.employees = response[1].data;
      this.goalKpis = response[2].data;
    }, error => {
      this.loaderService.stop();
    }, () => {
      this.loaderService.stop();
    });
  }

  updateGoalKpiSpaceStatus(goalKpi: any) {
    this.loaderService.start();
    this.selectedGoalKpiWeight = goalKpi.weight;
    this.kpiService.getToalWeightOfKpisByGoalKpiId(goalKpi.id).subscribe(response => {
     this.selectedGoalKpiTakenWeight = response.data;
    }, error => {
      this.loaderService.stop();
    }, () => {
      this.selectedGoalKpiRemainingWeight = this.selectedGoalKpiWeight - this.selectedGoalKpiTakenWeight;
      this.loaderService.stop();
    });
  }

  loadDataOnSearchResult(name: string, fieldName: string){
    if (fieldName === 'goalKpiId') {
      this.loaderService.start();
      this.goalKpiService.getGoalKpiByName(name)
      .subscribe(response => {
        this.goalKpis = response.data;
      }, error => {
        this.loaderService.stop();
      }, () => {
        this.loaderService.stop();
      });
    } else if (fieldName === 'departmentId') {
      this.loaderService.start();
      this.departmentService.getDepartmentByName(name)
      .subscribe(response => {
        this.departments = response.data;
      }, error => {
        this.loaderService.stop();
      }, () => {
        this.loaderService.stop();
      });
    } else if (fieldName === 'employeeId') {
      this.loaderService.start();
      this.employeeService.getEmployeeByName(name)
      .subscribe(response => {
        this.employees = response.data;
      }, error => {
        this.loaderService.stop();
      }, () => {
        this.loaderService.stop();
      });
    }
  }

  onKey(event: any) {
    console.log(event.target);
    console.log(event.target.attributes.formControlName.value);
    this.value = event.target.value;
    this.loadDataOnSearchResult(this.value, event.target.attributes.formControlName.value);
  }

  onSubmit() {
    this.loaderService.start();
    const {id, name, weight, goalKpiId, goalKpiName, departmentId, employeeId} = this.kpiForm.value;
    const kpiData = {
      name,
      weight: +weight,
      goalKpiName
    };

    if (this.data.isEdit) {
      this.kpiService.updateKpiIdByGoalIdKpiId(this.data.kpiData.goalKpiId, this.data.kpiData.id, kpiData)
        .subscribe(response => {
          this.alertService.success('Kpi updated successfully');
          this.dialogRef.close();
        }, error => {
          this.alertService.danger(error.error.message);
          this.loaderService.stop();
        }, () => {
          this.loaderService.stop();
        });
    } else {
      this.kpiService.addNewEmployeeIdByKpiIdEmployeeId(goalKpiId, employeeId, kpiData)
        .subscribe(response => {
          this.alertService.success('Kpi created successfully');
          this.dialogRef.close();
        }, error => {
          this.alertService.danger(error.error.message);
          this.loaderService.stop();
        }, () => {
          this.loaderService.stop();
        });
    }
  }

  onNoClick() {
    this.dialogRef.close({cancel: true});
  }

}


标签: angulartypescriptangular-reactive-forms

解决方案


尝试使您的button元素具有属性type="button"

<button id="addButton" type="button"

这将防止不需要的提交


推荐阅读