Angular Reactive Forms 数据更改验证不是外观更改验证
Angular Reactive Forms data change validation not cosmetic change validation
给定一个特定的 formGroup 及其对应的 HTML 表单
this.fieldForm = new FormGroup({
fieldId: new FormControl(null),
fieldName: new FormControl("", Validators.required),
sourceCreateBy: new FormControl(null),
sourceUpdateBy: new FormControl(null),
}, {validators: FieldFormValidators.invalidFormInput}) // some other logic
考虑 fieldName
= "WORKFORCE" 的场景。在 HTML 表单中,我编辑输入字段以首先将值设置为“WORKFORCE_1”,然后返回“WORKFORCE”。 formGroup 属性已从 pristine=true, dirty=false, touched=false
更改为 pristine=false, dirty=true, touched=true
。
因此表格有效。但实际上并没有发生数据变化。是否有任何内置的 FormControl 或 FormGroup 属性或其任意组合可以帮助我禁用“更新”按钮,或者我只能在之后进行此类验证事实(点击更新按钮)?
我可以创建一个自定义验证器来处理这个验证逻辑吗?
您可以创建自定义验证器“isDifferent”,但首先要重新使用函数创建表单的方式
getForm(data:any=null){
data=data|| {fieldID:null,fieldName:"",sourceCreateBy:null,sourceUpdateBy:null}
return FormGroup({
fieldId: new FormControl(null),
fieldName: new FormControl("", Validators.required),
sourceCreateBy: new FormControl(null),
sourceUpdateBy: new FormControl(null),
}, {validators: [FieldFormValidators.invalidFormInput,isDifferent(data)]})
getForm(data:any=null){
data=data|| {fieldID:null,fieldName:"",sourceCreateBy:null,sourceUpdateBy:null}
return FormGroup({
fieldId: new FormControl(data.fieldID),
fieldName: new FormControl(data.fieldName, Validators.required),
sourceCreateBy: new FormControl(data.sourceCreatedBy),
sourceUpdateBy: new FormControl(data.sourceUpdateBy),
}, {validators: [FieldFormValidators.invalidFormInput,isDifferent(data)]}) // some other logic
isDiferent(data:any){
return (control:AbtractControl)=>{
bool equal=true;
Object.keys(data).forEach(key=>{
equal=equal && data[key]==control.value[key]
})
return equal?{error:"must be different"}:null
}
}
你用作
this.fieldForm=this.getForm(..your object...)
更新:声明。好吧,上面的代码来自我想象的典型 REST。因此,如果我们有一个 Edit/Create 寄存器的组件,我们就有一个像
这样的路由器
{ path: 'hero/:id',component: HeroDetailComponent },
其中,可能的 id 值是数字或“新”,因此我们可以
url=hero/new //edit-component to create a new "hero"
url=hero/1 //edit-compoent to edit the hero with "id=1"
我们的组件,有一个表单并使用 reactiveForm 考虑到这一点,所以
constructor(private activatedRoute: ActivatedRoute,private service: HeroService) {}
form:FormGroup
status:string //here we store if "new" or "edit" to use for e.g.
//the button "submit" show a message "create" or "update"
ngOnInit() {
this.activatedRoute.paramMap.pipe(
switchMap(params => {
const id=params.get('id')
if (id=="new"){
this.form=this.getForm(); //create a empty form
this.status="new"
}
else{
//use "+id" to convert to number the "id"
this.service.getHeroe(+id).subscribe(res=>{
//here we has the "data of the "hero"
this.form=this.getForm(res) //create a form with the data of hero
this.status="edit"
})
}
);
}
我们的 .html 不需要复杂的输入处理程序,例如我们的按钮“提交”可以是
<!--see that the button is disabled if the form is invalid
if it's not invalid you need equal "disabled" to null,
**not** to false
--->
<button disabled="form.invalid?true:null">
{{status=="new"?"Create":"Update"}}
</button>
给定一个特定的 formGroup 及其对应的 HTML 表单
this.fieldForm = new FormGroup({
fieldId: new FormControl(null),
fieldName: new FormControl("", Validators.required),
sourceCreateBy: new FormControl(null),
sourceUpdateBy: new FormControl(null),
}, {validators: FieldFormValidators.invalidFormInput}) // some other logic
考虑 fieldName
= "WORKFORCE" 的场景。在 HTML 表单中,我编辑输入字段以首先将值设置为“WORKFORCE_1”,然后返回“WORKFORCE”。 formGroup 属性已从 pristine=true, dirty=false, touched=false
更改为 pristine=false, dirty=true, touched=true
。
因此表格有效。但实际上并没有发生数据变化。是否有任何内置的 FormControl 或 FormGroup 属性或其任意组合可以帮助我禁用“更新”按钮,或者我只能在之后进行此类验证事实(点击更新按钮)?
我可以创建一个自定义验证器来处理这个验证逻辑吗?
您可以创建自定义验证器“isDifferent”,但首先要重新使用函数创建表单的方式
getForm(data:any=null){
data=data|| {fieldID:null,fieldName:"",sourceCreateBy:null,sourceUpdateBy:null}
return FormGroup({
fieldId: new FormControl(null),
fieldName: new FormControl("", Validators.required),
sourceCreateBy: new FormControl(null),
sourceUpdateBy: new FormControl(null),
}, {validators: [FieldFormValidators.invalidFormInput,isDifferent(data)]})
getForm(data:any=null){
data=data|| {fieldID:null,fieldName:"",sourceCreateBy:null,sourceUpdateBy:null}
return FormGroup({
fieldId: new FormControl(data.fieldID),
fieldName: new FormControl(data.fieldName, Validators.required),
sourceCreateBy: new FormControl(data.sourceCreatedBy),
sourceUpdateBy: new FormControl(data.sourceUpdateBy),
}, {validators: [FieldFormValidators.invalidFormInput,isDifferent(data)]}) // some other logic
isDiferent(data:any){
return (control:AbtractControl)=>{
bool equal=true;
Object.keys(data).forEach(key=>{
equal=equal && data[key]==control.value[key]
})
return equal?{error:"must be different"}:null
}
}
你用作
this.fieldForm=this.getForm(..your object...)
更新:声明。好吧,上面的代码来自我想象的典型 REST。因此,如果我们有一个 Edit/Create 寄存器的组件,我们就有一个像
这样的路由器{ path: 'hero/:id',component: HeroDetailComponent },
其中,可能的 id 值是数字或“新”,因此我们可以
url=hero/new //edit-component to create a new "hero"
url=hero/1 //edit-compoent to edit the hero with "id=1"
我们的组件,有一个表单并使用 reactiveForm 考虑到这一点,所以
constructor(private activatedRoute: ActivatedRoute,private service: HeroService) {}
form:FormGroup
status:string //here we store if "new" or "edit" to use for e.g.
//the button "submit" show a message "create" or "update"
ngOnInit() {
this.activatedRoute.paramMap.pipe(
switchMap(params => {
const id=params.get('id')
if (id=="new"){
this.form=this.getForm(); //create a empty form
this.status="new"
}
else{
//use "+id" to convert to number the "id"
this.service.getHeroe(+id).subscribe(res=>{
//here we has the "data of the "hero"
this.form=this.getForm(res) //create a form with the data of hero
this.status="edit"
})
}
);
}
我们的 .html 不需要复杂的输入处理程序,例如我们的按钮“提交”可以是
<!--see that the button is disabled if the form is invalid
if it's not invalid you need equal "disabled" to null,
**not** to false
--->
<button disabled="form.invalid?true:null">
{{status=="new"?"Create":"Update"}}
</button>