如何向angular中的子窗体控件添加错误,而不使子控件静音';我们自己的验证器 this.form=this.fb.array([ 这个.fb.group({ 用户名:[空,验证程序。必需] }), 这个.fb.group({ 用户名:[空,验证程序。必需] }), ... ],uniqueUsernameValidator) const uniqueUsernameValidator=控件=>{ //找到副本 //当标记错误时 control.get('0.username').setErrors(IfthereisError)//其中'IfthereisError'可以为null }
不知何故,如何向angular中的子窗体控件添加错误,而不使子控件静音';我们自己的验证器 this.form=this.fb.array([ 这个.fb.group({ 用户名:[空,验证程序。必需] }), 这个.fb.group({ 用户名:[空,验证程序。必需] }), ... ],uniqueUsernameValidator) const uniqueUsernameValidator=控件=>{ //找到副本 //当标记错误时 control.get('0.username').setErrors(IfthereisError)//其中'IfthereisError'可以为null },angular,validation,angular-reactive-forms,angular-forms,angular-validation,Angular,Validation,Angular Reactive Forms,Angular Forms,Angular Validation,不知何故,uniqueUsernameValidator正在使子表单字段指定的required验证无效。如何解决此问题?为控件创建自定义验证程序时,应实现: 实现可以如下所示: const uniqueUsernameValidator = control => { const ifThereIsAnError = /* your logic .. find duplicate */ if(!ifThereIsAnError) { return null }
uniqueUsernameValidator
正在使子表单字段指定的required
验证无效。如何解决此问题?为控件创建自定义验证程序时,应实现:
实现可以如下所示:
const uniqueUsernameValidator = control => {
const ifThereIsAnError = /* your logic .. find duplicate */
if(!ifThereIsAnError) {
return null
}
return { unique: true }
}
在你的情况下,我想你的意思是setErrors
,而不是setError
?使用AbstractControl的错误设置程序时,您将使用setErrors
覆盖所有错误。如果要保留解决方案而不使用,则应在设置新错误之前获取错误:
const uniqueUsernameValidator = control => {
const errors: ValidationErrors = this.control.errors;
const keyNameOfYourError = 'unique';
// reset the last error before revalidating
if (errors && errors[keyNameOfYourError]) {
delete errors[keyNameOfYourError];
}
// ifThereIsAnError = execute your logic ... find duplicate
if (ifThereIsAnError) {
errors[keyNameOfYourError] = true;
this.control.setErrors(errors);
}
}
但我建议您使用该实现。尝试下面的方法
这将验证by user中提供的用户名是否都是唯一的我将这样解决它:
const uniqueUsernameValidator = control => {
const ifThereIsAnError = /* your logic .. find duplicate */
if(!ifThereIsAnError) {
return null
}
return { unique: true }
}
我的窍门
错误
属性
this.sub=this.usernamesArr.valueChanges.subscribe(=>updateControl(this.usernamesArr))代码>
此
我们可以访问它
uniqueInArray=uniqueInArray.bind(这个)代码>
{{usernamesArr.controls[i].controls.username.errors | json}
添加
ts
从“@angular/core”导入{Component};
进口{
造模工,
FormGroup,
形式上,
FormControl,
验证器,
抽象控制
}从“@angular/forms”;
从“rxjs”导入{Subscription};
const uniqueInArray=函数(
控件:抽象控件
):{uniqueInArray:string}空{
常量值=control.value;
const arr=this.usernamesArr.value为{username:string}[];
如果(value==null | | value.length==0 | | arr==null | | arr.length<2){
返回null;
}
返回arr.map(\u=>\ uUserName).filter(\u=>\ u==value).length>1
?{uniqueInArray:`${value}已存在。`}
:null;
};
const updateControls=函数(控件:FormArray):null{
control.controls.map((c:FormGroup)=>
c、 controls.username.updateValueAndValidity({
只有你自己:真的,
emit事件:false
})
);
返回null;
};
@组成部分({
选择器:“我的应用程序”,
templateUrl:“./app.component.html”,
样式URL:[“/app.component.css”]
})
导出类AppComponent{
分:认购;
usernamesArr:FormArray;
uniqueInArray=uniqueInArray.bind(this);
构造函数(私有formBuilder:formBuilder){}
恩戈尼尼特(){
this.usernamesArr=newformarray([]);
this.sub=this.usernamesArr.valueChanges.subscribe(\u=>
UpdateControl(this.usernamesArr)
);
}
createItem():抽象控件{
返回新表单组({
用户名:new FormControl(“,[Validators.required,this.uniqueInArray])
});
}
addItem():void{
this.usernamesArr.push(this.createItem());
}
恩贡德斯特罗(){
此.sub.取消订阅();
}
}
回答设置错误而不可能消除其他验证器错误这一更普遍的问题:
// Add - retaining existing
const errors = {
...control.errors,
myError: myValue
};
control.setErrors(errors);
// Remove - only the one we care about
const errors = { ...control.errors };
delete errors.myError;
control.setErrors(Object.keys(errors).length ? errors : null);
不要使用setErrors。如果一切正常,自定义验证器必须返回null,如果存在重复项,则必须返回一个对象。您可以有:this.form.errors、this.form.at(0).get('userName')。错误和/或this.form.at(1).get('userName')。错误正如其他人所说,您是否希望以这种方式设置错误是有争议的。我想,它的预期用途是返回一个对象或null,但有一次我需要与两个控件交互,因此使用了formgroup验证器,我需要在UI中显示错误,这对我来说,将错误放在控件而不是表单上是有意义的。因此,在我看来,在验证器中调用setErrors有一些用例——尽管比较少见。
<div [formGroup]="usernamesArr"
*ngFor="let item of usernamesArr.controls; let i = index;">
<div [formGroupName]="i">
<input formControlName="username" [placeholder]="'username' + i">
<pre style="color: red">
{{usernamesArr.controls[i].controls.username.errors | json}}
</pre>
</div>
</div>
<button (click)="addItem()">Add</button>
import { Component } from "@angular/core";
import {
FormBuilder,
FormGroup,
FormArray,
FormControl,
Validators,
AbstractControl
} from "@angular/forms";
import { Subscription } from "rxjs";
const uniqueInArray = function(
control: AbstractControl
): { uniqueInArray: string } | null {
const value = control.value;
const arr = this.usernamesArr.value as { username: string }[];
if (value == null || value.length === 0 || arr == null || arr.length < 2) {
return null;
}
return arr.map(_ => _.username).filter(_ => _ == value).length > 1
? { uniqueInArray: `${value} already exists.` }
: null;
};
const updateControls = function(control: FormArray): null {
control.controls.map((c: FormGroup) =>
c.controls.username.updateValueAndValidity({
onlySelf: true,
emitEvent: false
})
);
return null;
};
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
sub: Subscription;
usernamesArr: FormArray;
uniqueInArray = uniqueInArray.bind(this);
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.usernamesArr = new FormArray([]);
this.sub = this.usernamesArr.valueChanges.subscribe(_ =>
updateControls(this.usernamesArr)
);
}
createItem(): AbstractControl {
return new FormGroup({
username: new FormControl("", [Validators.required, this.uniqueInArray])
});
}
addItem(): void {
this.usernamesArr.push(this.createItem());
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
// Add - retaining existing
const errors = {
...control.errors,
myError: myValue
};
control.setErrors(errors);
// Remove - only the one we care about
const errors = { ...control.errors };
delete errors.myError;
control.setErrors(Object.keys(errors).length ? errors : null);