Angular 14自定义表单验证器失效问题求助
问题原因及修复方案
1. 表单组验证器配置键名错误
你在表单组的第二个参数里写的是Validators(大写开头),但Angular表单组的验证器配置键必须是小写的validators,这个拼写错误会直接导致Angular忽略你的自定义验证器配置。
2. 验证逻辑的判断条件不符合字段实际初始值
tcpPorts和udpPorts的初始值是[](空数组),不是null,所以你写的valueOfControlB === null和valueOfControlC === null永远不会成立,即便这两个字段没填值,验证器也不会判定为“未填写”。- 当用户未勾选icmp、也没填tcp/udp端口时,你的判断条件不满足,不会返回错误,最终导致验证器失效。
修复后的完整代码
newFWXForm = this.fb.group( { sspSelect: ["", Validators.required], requester: [this.loggedInUser], requesterContactInfo: [this.loggedInUserEmail], fwxDescription: ["", Validators.required], durationTypeSelect: ["Permanent", Validators.required], durationDate: [""], infraSelect: [""], sourceIPs: ["", Validators.required], DestAnyCheck: [false], SrcAnyCheck: [false], icmp: [false], destinationIPs: ["", Validators.required], tcpPorts: [], udpPorts: [], addDirectory: new FormControl(false), }, { // 修复:改为小写的validators validators: this.atleastOnePortValue("icmp", "tcpPorts", "udpPorts"), } ); private atleastOnePortValue(controlNameA: string, controlNameB: string, controlNameC: string): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { const formGroup = control as FormGroup; const icmpChecked = formGroup.get(controlNameA)?.value; const tcpPorts = formGroup.get(controlNameB)?.value; const udpPorts = formGroup.get(controlNameC)?.value; // 修复判断逻辑:icmp未勾选,且tcpPorts是空数组/无有效值,udpPorts同理 const hasNoPortSelection = !icmpChecked && (!tcpPorts || tcpPorts.length === 0) && (!udpPorts || udpPorts.length === 0); return hasNoPortSelection ? { atLeastOne: true } : null; }; }
额外注意事项
- 要在模板中正确显示验证错误,可通过
newFWXForm.hasError('atLeastOne')判断,提示用户“至少选择ICMP或填写TCP/UDP端口”。 - 如果
tcpPorts和udpPorts是自定义控件,需确保值变化时手动调用updateValueAndValidity()触发表单验证更新。
内容的提问来源于stack exchange,提问作者tsnov
相关产品推荐
相关产品推荐

