angular - 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});
}
}
解决方案
尝试使您的button
元素具有属性type="button"
<button id="addButton" type="button"
这将防止不需要的提交
推荐阅读
- ruby-on-rails - ROR:是什么导致未初始化的常量
- c - 从源代码编译 Squashfs 工具时出错
- python - Sypder:关闭绘图窗口后,如何让 pandas.plot(subplots =True) 再次显示?
- sql-server - 使用 SMTP Connection Manager-SSIS 2017 导入包
- angularjs - 从 AngularJS 前端到 Spring rest 后端的 CORS 问题
- r - 显示 y 轴 ggplot 中的每个中断
- laravel - Composer.json 说 php 补丁的无效字符串为星号(*)
- r - APE/Phangorn:如何包装尖端标签?
- c++ - tcp/ip ssh隧道传输数据时如何避免重复读取数据?
- android - 三星 Galaxy 8/9 和许多其他设备上的 Android FB 登录失败