Javascript 尝试使用Angular2表单模型执行条件验证器。正在尝试使用myForm.setValidators(),但没有';好像不行
我一直在尝试以离子/角度2使用模型形式。我有一个表单,我想做一些条件验证。用户从6个必填字段开始,然后可以在“手动”和“自动”处理之间进行选择。如果选择“自动”,则会呈现另外3个表单输入/选择。我希望这3个字段从非必填改为必填 以下是要开始的模型:Javascript 尝试使用Angular2表单模型执行条件验证器。正在尝试使用myForm.setValidators(),但没有';好像不行,javascript,angular,ionic-framework,ionic2,Javascript,Angular,Ionic Framework,Ionic2,我一直在尝试以离子/角度2使用模型形式。我有一个表单,我想做一些条件验证。用户从6个必填字段开始,然后可以在“手动”和“自动”处理之间进行选择。如果选择“自动”,则会呈现另外3个表单输入/选择。我希望这3个字段从非必填改为必填 以下是要开始的模型: this.myForm = this.formBuilder.group({ name: ['', Validators.compose([Validators.required, Validators.maxLength(45), Valida
this.myForm = this.formBuilder.group({
name: ['', Validators.compose([Validators.required, Validators.maxLength(45), Validators.minLength(2)])],
img: [''],
longDescription: ['', Validators.compose([Validators.required, Validators.maxLength(200)])],
shortDescription: ['', Validators.compose([Validators.required, Validators.maxLength(45)])],
processingType: [this.PROCESSING_TYPE.MANUAL],
discountType: ['' ],
discountRule: ['' ],
discountAmount: ['' ], // money, isNumbersOnly handled by custom validator
product: [''],
dateRuleDays: ['' ],
dateRuleTimeStart: ['' ],
dateRuleTimeEnd: ['' ],
startDate: ['', Validators.required],
expiryDate: ['', Validators.required ]
});
discountType、discountRule、discountAmount是我想切换为必填的3个字段
以下是我尝试过的:
调用setProcessingType fn的标记(如果需要,我可以提供完整的页面)
}
我还订阅了“processingType”值更改,其中我运行了与上述函数相同的逻辑
this.myForm.get('processingType').valueChanges.subscribe(data => this.onProcessingTypeChanged(data));
以下是我的日志中的一些屏幕截图,我正在尝试向其中添加验证程序:
开始(应该是怎样的)
单击“自动”后…为什么它们仍然为空?
单击“手动”后。。。现在需要吗?
基于上述怀疑,我怀疑
this.myForm.controls.updateValueAndValidty();
或
this.myForm.controls[key].updateValueAndValidity()
是问题所在,但正如我在代码中所评论的,这两个都抛出了“nota function”错误
我在谷歌上搜索了几乎所有条件验证、angular2表单模型、动态添加验证器等组合。。。这里的链接太多了,哈哈
希望这足以帮助诊断问题
提前感谢。更新:2017年4月3日 感谢对此的评论,这里的正确答案是显式地将控件上的错误设置回null 例如:
formCtrls.forEach((key, index) => {
if (this.myForm.controls && this.myForm.controls[key]) {
if (data === this.PROCESSING_TYPE.AUTOMATIC)
this.myForm.controls[key].setValidators([Validators.required]);
else {
this.myForm.controls[key].validator = [];
this.myForm.controls[key].setErrors(null); // CORRECT WAY- NOW VALIDATORS ARE GONE AND ERRORS ARE NULL
}
}
})
旧答案
看来我已经解决了这个问题,但对它感到不舒服。感觉像:
1)我错过了显而易见的正确方法
2)这是一个巨大的黑客
3.)这是一个bug(我非常怀疑这一点——我通常认为在这种情况下我是错的)
通过控件循环并使用setValidators()实际上是可行的,直到我尝试了上面@Sampath的答案(其工作方式与setValidators()相同,但没有解决问题),我才意识到这一点
为了解决这个问题,每次启动valueChanges观察者的回调时,我都会明确地将每个输入的值设置为空字符串
守则:
onProcessingTypeChanged(data) {
let formCtrls = ['discountType', 'discountRule', 'discountAmount', 'dateRuleDays', 'dateRuleTimeStart', 'dateRuleTimeEnd'];
let add = [Validators.required];
let empty = [];
let newValue;
if (data === this.PROCESSING_TYPE.AUTOMATIC) newValue = "";
else newValue = " "; // SET TO AN EMPTY STRING
this.myForm.patchValue({
discountType: newValue,
discountRule: newValue,
discountAmount: newValue,
product: newValue,
dateRuleDays: newValue,
dateRuleTimeStart: newValue,
dateRuleTimeEnd: newValue,
});
formCtrls.forEach((key, index) => {
if (this.myForm.controls && this.myForm.controls[key]) {
if (data === this.PROCESSING_TYPE.AUTOMATIC)
this.myForm.controls[key].setValidators([Validators.required]);
else
this.myForm.controls[key].setValidators([]);
}
})
}
在仔细研究之后,似乎正在针对此返回的闭包对错误(myForm.controls[key].errors)进行内部处理:
function(control) {
return isEmptyInput(control.value) : { 'required': true } ? null;
}
因此,据我所知,通过不将每个值重置为空字符串(我觉得奇怪,b/c空字符串是错误的,但在闭包中它传递的不是空输入),angular将每个输入注册为空,并将errors对象设置为{required:true},因此,即使在每个输入上没有必需的验证器,将表单注册为仍然无效
不会将此标记为正确-如果有人纠正此逻辑或有类似问题,则希望得到反馈
onProcessingTypeChanged(data) {
let formCtrls = ['discountType', 'discountRule', 'discountAmount', 'dateRuleDays', 'dateRuleTimeStart', 'dateRuleTimeEnd'];
let add = [Validators.required];
let empty = [];
let newValue;
if (data === this.PROCESSING_TYPE.AUTOMATIC) newValue = "";
else newValue = " "; // SET TO AN EMPTY STRING
this.myForm.patchValue({
discountType: newValue,
discountRule: newValue,
discountAmount: newValue,
product: newValue,
dateRuleDays: newValue,
dateRuleTimeStart: newValue,
dateRuleTimeEnd: newValue,
});
formCtrls.forEach((key, index) => {
if (this.myForm.controls && this.myForm.controls[key]) {
if (data === this.PROCESSING_TYPE.AUTOMATIC)
this.myForm.controls[key].setValidators([Validators.required]);
else
this.myForm.controls[key].setValidators([]);
}
})
function(control) {
return isEmptyInput(control.value) : { 'required': true } ? null;
}