gpt4 book ai didi

javascript - 尝试使用 Angular2 表单模型做条件验证器。尝试使用 myForm.setValidators(),但似乎不起作用

转载 作者:行者123 更新时间:2023-11-29 23:49:41 25 4
gpt4 key购买 nike

我一直在尝试在 Ionic/Angular2 中使用模型形式。我有一个表格,我想做一些条件验证。用户从 6 个必填字段开始,然后可以在“手动”和“自动”处理之间进行选择。如果选择“自动”,则会呈现 3 个以上的表单输入/选择。我希望这 3 个字段从不需要变为必需。

这是开始的模型:

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 的标记(如果需要,我可以提供完整页面)

<!-- automatic or manual -->
<h4 margin-top text-center>Processing Type</h4>
<ion-row text-center>
<ion-col width-50>
<button class="width-80" color="primary" (click)="setProcessingType(PROCESSING_TYPE.MANUAL)" ion-button margin-top>{{ PROCESSING_TYPE.MANUAL }}</button>
</ion-col>
<ion-col width-50>
<button class="width-80" color="primary" (click)="setProcessingType(PROCESSING_TYPE.AUTOMATIC)" ion-button margin-top>{{ PROCESSING_TYPE.AUTOMATIC }}</button>
</ion-col>
</ion-row>

当用户在“手动”和“自动”按钮之间单击时,将调用 setProcessingType。 type: string 是我将设置为 processingType 的新值。

setProcessingType(type: string): void {

this.myForm.patchValue({ // i welcome comments to correct this to 'setValue()' if needed
processingType: type
});

let formCtrls = ['discountType', 'discountRule', 'discountAmount', 'dateRuleDays', 'dateRuleTimeStart', 'dateRuleTimeEnd'];
let add = [Validators.required];
let empty = [];

formCtrls.forEach((key, index) => {
if (this.myForm.controls && this.myForm.controls[key]) {
if (type === this.PROCESSING_TYPE.AUTOMATIC) {
this.myForm.controls[key].setValidators([Validators.required]);
} else {
console.log('resetting validators...');
this.myForm.controls[key].setValidators([]);
console.log('errors on : ', key, this.myForm.controls[key].errors);
// this.myForm.controls[key].markAsUntouched(); // attempt 3928
// this.myForm.controls[key].markAsPristine() // attempt 3929
//this.myForm.controls.updateValueAndValidty(); // this throws an error
}
}
})

console.log('new form controls: ', this.myForm.controls);

我还订阅了“processingType”valueChanges,我在其中运行与上述函数相同的逻辑

    this.myForm.get('processingType').valueChanges.subscribe(data => this.onProcessingTypeChanged(data));

以下是我尝试向其中添加验证器的值的日志中的一些屏幕截图:

开始(应该怎样)...

点击“自动”后...为什么它们仍然为空?

点击“手动”后...现在需要它们了吗? enter image description here

基于以上怀疑,我怀疑

this.myForm.controls.updateValueAndValidty();

或者 this.myForm.controls[key].updateValueAndValidity();

是问题所在,但正如我在代码中评论的那样,这两个问题都引发了“不是函数”错误。

我用谷歌搜索了条件验证、angular2 表单模型、动态添加验证器等的几乎所有组合...链接太多,无法在此处列出,哈哈。

希望这足以让某人帮助诊断问题。

提前致谢。

最佳答案

更新:2017 年 4 月 3 日

感谢对此 post 的评论,这里的正确答案是将控件上的错误显式设置回 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.) 这是一个巨大的 hack。

3.) 这是一个错误(我对此非常怀疑 - 我通常认为在这种情况下我错了)。

遍历控件并使用 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 将每个输入注册为空,并将错误对象设置为 { required: true },因此将表单注册为仍然无效,即使每个输入都没有必需的验证器。

不会将此标记为正确 - 如果有人更正此逻辑或有类似问题,我们希望对此提供反馈。

关于javascript - 尝试使用 Angular2 表单模型做条件验证器。尝试使用 myForm.setValidators(),但似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43152697/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com