angular - 必填字段验证器不起作用Angular 7反应形式
问题描述
我试图实现控件WebsiteUrl
字段所需的验证器。FormArray
在初始表单加载时,我可以看到 true 的值,即form.valid
打印在 UI 上。当我尝试清除控件时,表单仍然有效。我正在尝试禁用保存按钮,并在控件下方显示一个标签,突出显示该字段尚未填充。
用户界面
html
<div class="form-group row">
<label for="inputEmail" class="col-md-2 col-form-label modal-label ">Websites</label>
<div class="col-md-10">
<div class="form-group row">
<div class="col-md-4">
<label style="background-color:#dfdfdf" for="inputEmail">Website URL</label>
</div>
<div class="col-md-3">
<label style="background-color:#dfdfdf" for="inputEmail">User Name</label>
</div>
<div class="col-md-3">
<label style="background-color:#dfdfdf" for="inputEmail">Password</label>
</div>
</div>
</div>
<div class="col-md-10 offset-md-2">
<div formArrayName="Websites"
*ngFor="let item of frmFirm.get('Websites').controls; let i = index; let last = last">
<div [formGroupName]="i">
<div class="form-group row">
<div class="col-md-4">
<div *ngIf="!EditMode">{{FirmDetails.Websites[i].WebsiteUrl}}</div>
<input *ngIf="EditMode" formControlName="WebsiteUrl" class="form-control form-control-sm" />
{{frmFirm.valid}}
<label *ngIf="EditMode && !frmFirm.valid" style="color:red" for="inputEmail">Please enter Website URL</label>
</div>
<div class="col-md-3">
<div *ngIf="!EditMode">{{FirmDetails.Websites[i].Username}}</div>
<input *ngIf="EditMode" formControlName="Username" class="form-control form-control-sm" />
</div>
<div class="col-md-3">
<div *ngIf="!EditMode">{{FirmDetails.Websites[i].Password}}</div>
<input *ngIf="EditMode" formControlName="Password" class="form-control form-control-sm" />
</div>
<div class="col-md-1" *ngIf="EditMode">
<button style="color: #c45703; border-color: #c45703; padding:1px" class="fa fa-trash" (click)="removeWebsite(i)"></button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-group row" *ngIf="EditMode">
<div class="col-md-2 offset-md-2">
<button class="btn-firm" type="button" (click)="addWebsite()">Add Website</button>
</div>
</div>
<div class="btn-toolbar" style="padding-top:40px;">
<span *ngIf="EditMode"><button [disabled]="!frmFirm.valid" type="submit" class="btn btn-primary btn-view-all btn mr-3">Save</button>
</span>
零件
constructor(private _fb: FormBuilder, private firmService: FirmService,
private commonDataService: CommonDataService, private notify: NotifyService,private changeDetectorRef: ChangeDetectorRef) {
// this.changeDetectorRef.markForCheck();
}
ngOnInit() {
this.initializeFormModel();
this.getFirmDetails();
}
initializeFormModel() {
this.frmFirm = this._fb.group({
FirmName: [''],
DateFounded: [''],
Websites: this._fb.array([
this.createWebsite()
])
});
}
public addWebsite(): void {
this.Websites.push(this.createWebsite());
this.frmFirm.setErrors({'dirty': false});
}
public removeWebsite(index: number): void {
const websites = this.frmFirm.get('Websites') as FormArray;
if (websites.length === 1)
{
websites.reset();
return;
}
websites.removeAt(index);
this.frmFirm.setErrors({'dirty': true});
}
private createWebsite(): FormGroup {
return this._fb.group({
WebsiteUrl: ['', Validators.required],
Username: [''],
Password: ['']
});
}
get Websites(): FormArray {
return <FormArray>this.frmFirm.get('Websites');
}
const websiteGroup = FirmDetails.Websites.map(website => {
return this._fb.group({
FirmWebsiteId: [website.FirmWebsiteId],
WebsiteUrl: [website.WebsiteUrl],
Username: [website.Username],
Password: [website.Password],
FirmId: [website.FirmId]
});
});
const wesbiteFormArray: FormArray = this._fb.array(websiteGroup);
this.frmFirm.setControl('Websites', wesbiteFormArray);
}
getFirmDetails() {
if (this.FirmId != null) {
this.firmService.getFirmDetails(this.FirmId).subscribe((data: any) => {
this.FirmDetails = data;
this.FirmId = this.FirmDetails.FirmId;
this.setFormValues(this.FirmDetails);
this.EditMode = false;
this.changeDetectorRef.markForCheck();
});
} else {
this.FirmDetails = {};
this.EditMode = true;
}
}
解决方案
Using FormGroup.get(CONTROL)
returns a FormControl
instance you can use to access specific values and checks for every control
for example FormControl.hasError
and FormControl.touched
Try the code below:
<label
*ngIf="item.get('WebsiteUrl').hasError('required') &&
item.get('WebsiteUrl').touched">Please enter Website URL
</label>
Also including Validators.required
into the initial websiteGroup
should fix the button not being disabled
const websiteGroup = FirmDetails.Websites.map(website => {
return this._fb.group({
FirmWebsiteId: [website.FirmWebsiteId],
WebsiteUrl: [website.WebsiteUrl, Validators.required],
Username: [website.Username],
Password: [website.Password],
FirmId: [website.FirmId]
});
});
推荐阅读
- c# - 我怎样才能使这个网格可滚动?
- javascript - keydown 上的多个快捷键在 Typescript 中不起作用
- python - Python 模块安装:指定外部库依赖项的位置
- mongodb - 查找所有位置 $geoWithin $geoIntersects
- reactjs - Heroku 没有连接到 Mongo Atlas DB?
- python - 记录一个协程感知变量
- php - Laravel响应资源png
- python - 通过 SQL Alchemy 错误连接到 Exasol DB
- php - 如何在php中将两个变量字符串存储在二维数组中
- python - subprocess.Popen() 一个带有无限循环的python文件永远不会调用该文件