【问题标题】:How to add custom validation for ngModelGroup in Template driven forms如何在模板驱动的表单中为 ngModelGroup 添加自定义验证
【发布时间】:2019-02-15 02:19:15
【问题描述】:

我正在使用模板驱动的表单方法。我想在ngModelGroup 上添加自定义验证。也就是说,如果填写了一个字段,则所有字段也必须填写。

<form #f="ngForm">
      <div ngModelGroup="address">
        <input type="email" name="house_number" class="form-control" ngModel>
        <input type="email" name="street_number" class="form-control" ngModel>
      </div>
</form>

我在网上搜索,只找到像this 这样的文章,它只在输入级别而不是ngModelGroup 级别讨论自定义验证。其他文章讨论了我无法实现的响应式表单。

任何帮助将不胜感激。

【问题讨论】:

    标签: angular angular-forms


    【解决方案1】:

    由于您处理模板驱动的表单,因此最好创建将验证器添加到您的地址组的指令:

    @Directive({
      selector: '[ngModelGroup][requiredIfOneFilledValidator]',
      providers: [{
        provide: NG_VALIDATORS,
        useExisting: forwardRef(() => AddressValidator),
        multi: true
      }]
    })
    export class RequiredIfOneFilledValidator implements Validator {
      validate(group: AbstractControl): ValidationErrors | null {
        const controls = (group as FormGroup).controls; // we expect FormGroup here
        const controlNames = Object.keys(controls);
        const filledCount = controlNames.filter(name => !!controls[name].value).length;
    
        return filledCount > 0 && filledCount < controlNames.length ? { required: true } : null;
      }
    }
    

    现在您可以轻松地在模板中使用此验证器:

    <div ngModelGroup="address" requiredIfOneFilledValidator>
    

    如果你想检查组是否有效,只需使用模板引用变量:

    <div ngModelGroup="address" requiredIfOneFilledValidator #addressGroup="ngModelGroup">
       ...
    </div>
    <p>Group valid? {{addressGroup.valid}}</p>
    

    或者只检查整个表单的状态:

    Form valid? {{ f.valid }}
    

    Ng-run Example

    【讨论】:

    • 感谢您的回答。我将console.log() 转换为validate 方法。 validate 正在运行 5 次以上。你能说出原因吗?
    • 这就是角度验证器的工作方式。 Angular 在每个控件更改时触发验证。这里我们有addFormGroupaddControl(第一个控件添加到组),setValueaddControl(第二个控件添加到组),setValue调用验证函数的处理程序
    【解决方案2】:

    如果担心创建新指令,您可以在现有组件中进行更改。您可以添加一个 div 以在 html 文件中向用户显示错误消息。

    <form (ngSubmit)="validateData(f)" #f="ngForm">
    <div  ngModelGroup="address">
    <input type="email" name="house_number" class="form-control" required ngModel>
    <div style="color:red;display:none;" id="errorMsg">
    This field cannot be empty
    </div>
    <input type="email" name="street_number" class="form-control" ngModel>
    </div>
    <button type="submit">Submit</button>
    </form>
    

    在组件部分,您可以根据需要访问表单值并显示/隐藏验证。

    address:any;
    validateData(f) {
    
     console.log("Form Values : "+ f.value);
    
     this.address = f.value.address;
    
     if(!this.address.house_number){
        //code to show/hide the message
        var x = document.getElementById("errorMsg");
        x.style.display="block";
     }
    
     //to check form validity
     if (f.valid) {
        //do something 
      }
    
     }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-07
      • 1970-01-01
      • 2017-12-02
      • 2021-04-14
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多