我创建了一个组件"form-page"以"形式"模块:
form-page.component.html:
<form [formGroup]="form" (submit)="onSubmit()">
<div>
<label for="carmodel">Car Model:</label>
<input type="text" class="form-control" formControlName="carmodel">
<div *ngIf="form.controls['carmodel'].touched && form.controls['carmodel'].errors">
<div *ngIf="form.controls['carmodel'].hasError('required')" class="error">Carmodel is required.</div>
<div *ngIf="form.controls['carmodel'].hasError('minlength')">Carmodel should be minimum 3 characters.</div>
</div>
</div>
<div>
<label for="carnum">Car Number:</label>
<input type="text" class="form-control" formControlName="carnum">
<div *ngIf="form.controls['carnum'].touched && form.controls['carnum'].errors">
<div *ngIf="form.controls['carnum'].hasError('required')" class="error">carnum is required.</div>
</div>
</div>
<div>
<label for="contactNumber">Contact Number:</label>
<input type="text" class="form-control" formControlName="contactNumber">
<div *ngIf="form.controls['contactNumber'].touched && form.controls['contactNumber'].errors">
<div *ngIf="form.controls['contactNumber'].hasError('required')" class="error">Contact number is required.</div>
</div>
</div>
<div>
<label>Type of Service:</label>
<div>
<label><input type="radio" name="option" value="Waterwash" formControlName="option"> Waterwash </label>
</div>
<div>
<label><input type="radio" name="option" value="Fullservice" formControlName="option"> Fullservice </label>
</div>
<div *ngIf="form.controls['option'].touched && form.controls['option'].invalid">
<div class="error">Please select an option</div>
</div>
</div>
<div>
<label>Addons:</label>
<div>
<label><input type="checkbox" value="10%off First service visit" formControlName="checkbox"> 10%off First service visit</label>
</div>
<div>
<label><input type="checkbox" value="10%off Waterwash" formControlName="checkbox"> 10%off Waterwash</label>
</div>
<div>
<label><input type="checkbox" value="Free AC Inspection" formControlName="checkbox"> Free AC Inspection</label>
</div>
<div *ngIf="form.controls['checkbox'].touched && form.controls['checkbox'].invalid">
<div class="error">Please select at least one Addon</div>
</div>
</div>
<div>
<label>State:</label>
<select formControlName="state" (change)="onStateChange()">
<option *ngFor="let state of states" [value]="state">{{state}}</option>
</select>
<div *ngIf="form.controls['state'].touched && form.controls['state'].invalid">
<div class="error">Please select a state</div>
</div>
</div>
<div>
<label>City:</label>
<select formControlName="city">
<option *ngFor="let city of cities[form.controls['state'].value]" [value]="city">{{city}}</option>
</select>
<div *ngIf="form.controls['city'].touched && form.controls['city'].invalid">
<div class="error">Please select a city</div>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" (click)="Reset()">Reset</button>
<button (click)="goBack()">back</button>
</form>
form-page.component.ts:
import { Component } from '@angular/core';
import { Location } from '@angular/common';
//
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
//
import { CarServiceService } from 'src/app/services/car-service.service';
@Component({
selector: 'app-form-page',
templateUrl: './form-page.component.html',
styleUrls: ['./form-page.component.css']
})
export class FormPageComponent {
form: FormGroup;
states: string[] = ['Tamilnadu', 'Kerala', 'Karnataka','Maharastra'];
cities: {[key: string]: string[]} = {
'Tamilnadu': ['Chennai', 'Coimbatore','Madurai'],
'Kerala': ['Trivandrum','Kochi','Kollam'],
'Karnataka': ['Bangalore', 'Mysore'],
'Maharastra': ['Mumbai', 'Pune']
};
constructor(private fb: FormBuilder,private location : Location,private carServiceService :CarServiceService) {
this.form = this.fb.group({
carmodel :['', [Validators.required, Validators.minLength(3)]],
carnum :['', [Validators.required]],
contactNumber: ['', [Validators.required, Validators.pattern(/^d{10}$/)]],
option: ['', Validators.required],
checkbox: ['', Validators.required],
state: ['', Validators.required],
city: ['', Validators.required]
});
}
goBack():void{
this.location.back();
}
onSubmit() {
if (this.form.valid) {
this.carServiceService.addCar(this.form.value).subscribe(response =>{
console.log(response);
});
} else {
// Form is invalid, display error messages
this.form.markAllAsTouched();
}
}
Reset(){
this.form.reset();
}
onStateChange() {
const state = this.form.controls['state'].value;
this.form.controls['city'].setValue('');
if (state) {
this.form.controls['city'].enable();
} else {
this.form.controls['city'].disable();
}
}
//
}
创建名为"car-service"的服务;发布:
car-service.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class CarServiceService {
constructor(private http: HttpClient) { }
addCar(formData : any): Observable<any>{
return this.http.post<any>('https://localhost:7095/api/Forms/submit-form',formData);
}
}
我正试图将表单值发布到API。当我点击提交,我得到一个错误400。
POST https://localhost:7095/api/Forms/submit-form 400
错误:
ERROR HttpErrorResponse {headers: HttpHeaders, status: 400, statusText: 'OK', url: 'https://localhost:7095/api/Forms/submit-form', ok: false, …}error: {type: 'https://tools.ietf.org/html/rfc7231#section-6.5.1', title: 'One or more validation errors occurred.', status: 400, traceId: '00-88c37085e17ce434f174cf65d020c28e-1bd09d34125cb2dc-00', errors: {…}}headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}message: "Http failure response for https://localhost:7095/api/Forms/submit-form: 400 OK"name: "HttpErrorResponse"ok: falsestatus: 400statusText: "OK"url: "https://localhost:7095/api/Forms/submit-form"[[Prototype]]:
在asp.net-core web API中:
FormData.cs:
namespace AngularApi.Model
{
public class FormData
{
public string Carmodel { get; set; }
public string Carnum { get; set; }
public string ContactNumber { get; set; }
public string Option { get; set; }
public List<string> Checkbox { get; set; }
public string State { get; set; }
public string City { get; set; }
}
}
这里是我的FormController在API:
private static List<FormData> formsDataList = new List<FormData>();
[HttpPost("submit-form")]
public IActionResult SubmitForm([FromBody] FormData formData)
{
// process the form data
string carmodel = formData.Carmodel;
string carnum = formData.Carnum;
string contactNumber = formData.ContactNumber;
string option = formData.Option;
List<string> checkbox = formData.Checkbox;
string state = formData.State;
string city = formData.City;
// validate the form data
// if (string.IsNullOrWhiteSpace(carmodel) || string.IsNullOrWhiteSpace(carnum) || string.IsNullOrWhiteSpace(contactNumber) || string.IsNullOrWhiteSpace(option) || checkbox == null || checkbox.Count == 0 || string.IsNullOrWhiteSpace(state) || string.IsNullOrWhiteSpace(city))
// {
// return BadRequest(new { Message = " Enter the required fields." });
// }
formsDataList.Add(formData);
// return Ok(new { Message = "Form submitted successfully." });
return Ok(formData);
}
输入甚至没有击中API。所以我怀疑问题是与HTTPClient和复选框。我想问题出在复选框上。因为如果我从HTML表单和API中完全删除复选框字段,它就可以完美地工作,我就可以向API发送值了。
谁能告诉我如何解决这个问题?
如果您记录表单值,您将得到以下内容:
carmodel: "kia"
carnum: "123"
checkbox: true
city: "Chennai"
contactNumber: "456"
option: "Waterwash"
state: "Tamilnadu"
我想你也看到问题了。布尔不是字符串列表。除此之外,您为所有三个选项提供了相同的控件名称。
您可以使用字符串数组或更好的FormArray
,并使用ngFor
生成复选框。
首先我定义了复选框的值:
checkboxes = [
{ value: '10%off First service visit', name: '10%off First service visit' },
{ value: '10%off Waterwash', name: '10%off Waterwash' },
{ value: 'Free AC Inspection', name: 'Free AC Inspection' },
];
顺便说一句,对我来说,把值作为字符串有点不常见。我的意思是,你更愿意将id存储在数据库中。但是不管怎样。
然后在表单生成器
中使用FormArray
checkbox: new FormArray([], Validators.required)
,并为它创建一个getter
get checkboxesFormArray() {
return this.form.controls['checkbox'] as FormArray;
}
之后填充
addCheckboxes() {
this.checkboxes.forEach(() =>
this.checkboxesFormArray.push(new FormControl(''))
);
}
并添加一个事件处理程序来处理选中的更改事件
checkedChanged(e) {
let index = this.checkboxes.findIndex(
(item) => item.value === e.target.value
);
if (e.target.checked) {
this.checkboxesFormArray.controls[index].setValue(e.target.value);
} else {
this.checkboxesFormArray.controls[index].setValue('');
}
}
设置appr。控件值设置为所选字符串。
模板是这样的
<div>
<label>Addons:</label>
<div *ngFor="let cbx of checkboxesFormArray.controls; let i = index">
<label formArrayName="checkbox">
<input type="checkbox" [formControlName]="i" (change)="checkedChanged($event)" [value]="checkboxes[i].value">
{{checkboxes[i].name}}
</label>
</div>
</div>
在这里你可以找到一个工作的stackblitz演示。
如果这是你正在寻找的,那么请将其标记为答案。
您可以尝试使用<mat-selection-list>
而不是<input type=checkbox>
。将始终返回布尔值。它将返回所选值的数组。代码将是:
<mat-selection-list formControlName="checkbox">
<mat-list-option value="10%off First service visit"> 10%off First service
visit</mat-list-option>
<mat-list-option value="10%off Waterwash" 10%off Waterwash</label></mat-
list-option>
<mat-list-option value="Free AC Inspection"> Free AC Inspection</mat-
list-option>
</mat-selection-list>
注意:MatSelectionList是Angular Material的一个组件。你必须先在你的模块中导入它。