Angular 当表单中有多个时,FormControls 始终有效
Angular FormControls Always Valid When More Than One In Form
我有两个使用 FormControl 的输入始终显示为有效,但如果我取出一个,则其余输入将如预期的那样 valid/invalid。我会为一个 ControlGroup 更改两个表单控件,但是 1.) 我想了解我做错了什么和 2.) 我需要访问一个表单控件以实现组件中的自动完成功能。
相关HTML:
<form
fxLayout="column"
fxLayoutAlign="center center"
(ngSubmit)="onSubmit(status, count)"
#statusForm="ngForm"
>
<!-- Status Input -->
<div>
<mat-form-field>
<input
matInput placeholder="Status"
[formControl]="statusFormControl"
[errorStateMatcher]="matcher"
[matAutocomplete]="auto"
[(ngModel)]="status"
name="status"
required
>
<mat-error *ngIf="statusFormControl.hasError('required')">
Status is <strong>required</strong>
</mat-error>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let status of filteredStatusList | async" [value]="status.name">
{{ status.name }}
</mat-option>
</mat-autocomplete>
</div>
<!-- Count Input -->
<mat-form-field>
<input
matInput placeholder="Count"
[formControl]="countFormControl"
type="number"
min="1"
[(ngModel)]="count"
name="count"
required
>
<mat-error *ngIf="countFormControl.hasError('required')">
Count must be a <strong>number</strong>
</mat-error>
</mat-form-field>
{{statusForm.valid}}
{{statusForm.invalid}}
<button
mat-raised-button color="primary"
*ngIf="statusForm.valid"
type="submit"
[disabled]="statusForm.invalid"
>
Add
</button>
和 TS:
export class ... {
statusFormControl = new FormControl('', [
Validators.required
]);
countFormControl = new FormControl('', [
Validators.required
]);
...
constructor() {
this.filteredStatusList = this.statusFormControl.valueChanges
.pipe(
startWith(''),
map(status => status ? this.filterStatusList(status) : this.allStatuses.slice())
);
}
filterStatusList(statusName: string) {
return this.allStatuses.filter(status =>
status.name.toLowerCase().indexOf(statusName.toLowerCase()) === 0);
}
}
这是我的一个使用反应形式的样子(见下文)。注意表单的 formGroup
指令。而且我使用了 formControlName
指令而不是 formControl
指令......但是两者都可以。
HTML
<form class="form-horizontal"
novalidate
(ngSubmit)="save()"
[formGroup]="customerForm">
<fieldset>
<div class="form-group">
<label class="col-md-2 control-label"
for="firstNameId">First Name</label>
<div class="col-md-8">
<input class="form-control"
id="firstNameId"
type="text"
placeholder="First Name (required)"
formControlName="firstName" />
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label"
for="lastNameId">Last Name</label>
<div class="col-md-8">
<input class="form-control"
id="lastNameId"
type="text"
placeholder="Last Name (required)"
formControlName="lastName" />
</div>
</div>
</fieldset>
</form>
组件Class
customerForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit(): void {
this.customerForm = this.fb.group({
firstName: ['', [Validators.required, Validators.minLength(3)]],
lastName: ['', [Validators.required, Validators.maxLength(50)]]
});
}
此外,如果您需要使用上述语法引用其中一个 FormControl,您可以这样做:
this.customerForm.get('lastName')
您的方法将如下所示:
this.filteredStatusList = this.myForm.get('status').valueChanges
.pipe(
startWith(''),
map(status => status ? this.filterStatusList(status) : this.allStatuses.slice())
);
我有两个使用 FormControl 的输入始终显示为有效,但如果我取出一个,则其余输入将如预期的那样 valid/invalid。我会为一个 ControlGroup 更改两个表单控件,但是 1.) 我想了解我做错了什么和 2.) 我需要访问一个表单控件以实现组件中的自动完成功能。
相关HTML:
<form
fxLayout="column"
fxLayoutAlign="center center"
(ngSubmit)="onSubmit(status, count)"
#statusForm="ngForm"
>
<!-- Status Input -->
<div>
<mat-form-field>
<input
matInput placeholder="Status"
[formControl]="statusFormControl"
[errorStateMatcher]="matcher"
[matAutocomplete]="auto"
[(ngModel)]="status"
name="status"
required
>
<mat-error *ngIf="statusFormControl.hasError('required')">
Status is <strong>required</strong>
</mat-error>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let status of filteredStatusList | async" [value]="status.name">
{{ status.name }}
</mat-option>
</mat-autocomplete>
</div>
<!-- Count Input -->
<mat-form-field>
<input
matInput placeholder="Count"
[formControl]="countFormControl"
type="number"
min="1"
[(ngModel)]="count"
name="count"
required
>
<mat-error *ngIf="countFormControl.hasError('required')">
Count must be a <strong>number</strong>
</mat-error>
</mat-form-field>
{{statusForm.valid}}
{{statusForm.invalid}}
<button
mat-raised-button color="primary"
*ngIf="statusForm.valid"
type="submit"
[disabled]="statusForm.invalid"
>
Add
</button>
和 TS:
export class ... {
statusFormControl = new FormControl('', [
Validators.required
]);
countFormControl = new FormControl('', [
Validators.required
]);
...
constructor() {
this.filteredStatusList = this.statusFormControl.valueChanges
.pipe(
startWith(''),
map(status => status ? this.filterStatusList(status) : this.allStatuses.slice())
);
}
filterStatusList(statusName: string) {
return this.allStatuses.filter(status =>
status.name.toLowerCase().indexOf(statusName.toLowerCase()) === 0);
}
}
这是我的一个使用反应形式的样子(见下文)。注意表单的 formGroup
指令。而且我使用了 formControlName
指令而不是 formControl
指令......但是两者都可以。
HTML
<form class="form-horizontal"
novalidate
(ngSubmit)="save()"
[formGroup]="customerForm">
<fieldset>
<div class="form-group">
<label class="col-md-2 control-label"
for="firstNameId">First Name</label>
<div class="col-md-8">
<input class="form-control"
id="firstNameId"
type="text"
placeholder="First Name (required)"
formControlName="firstName" />
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label"
for="lastNameId">Last Name</label>
<div class="col-md-8">
<input class="form-control"
id="lastNameId"
type="text"
placeholder="Last Name (required)"
formControlName="lastName" />
</div>
</div>
</fieldset>
</form>
组件Class
customerForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit(): void {
this.customerForm = this.fb.group({
firstName: ['', [Validators.required, Validators.minLength(3)]],
lastName: ['', [Validators.required, Validators.maxLength(50)]]
});
}
此外,如果您需要使用上述语法引用其中一个 FormControl,您可以这样做:
this.customerForm.get('lastName')
您的方法将如下所示:
this.filteredStatusList = this.myForm.get('status').valueChanges
.pipe(
startWith(''),
map(status => status ? this.filterStatusList(status) : this.allStatuses.slice())
);