首页 文章

Angular 5反应形式条件验证

提问于
浏览
0

我有一个大型的反应形式,它具有条件验证,基于从应该触发验证的多选输入所做的选择 . 我注意到,当选择或取消选择某个项目时,整个表单被标记为无效(使用ng-invalid类),但内部子输入在它们应该有效时表示无效,反之亦然UNTIL你要么关注输入或者如果您只是在页面上的任意位置单击选择 .

https://stackblitz.com/edit/angular-6mbw5r

Repro步骤:

  • 打开开发工具并注意整个标记在加载时设置为ng-invalid . 应该无效的唯一字段是DEA表单字段 .

  • 从服务水平多重选择中删除受控物质 . 请注意,表单从 class="ng-untouched ng-pristine ng-invalid"class="ng-untouched ng-invalid ng-dirty" UNTIL单击 ng-select (或任何其他字段)组件 . 然后它转到 class="ng-dirty ng-touched ng-valid" .

  • 注意必要字段如何根据表单的当前状态进行更改或不更改,直到发生其他一些操作(如更改焦点) .

备用Repro步骤:

  • 加载页面并选中Veteranarian复选框 . 这应该会触发状态许可证无效,但直到您点击其他位置才会触发 .

我有OnPush变化检测,并确保在任何地方我做任何条件变化,我 markForCheck() . 我还将整个表单组更新策略设置为 'change' ,根据我的理解,应该在表单字段更改值后立即触发验证 .

我已经阅读了很多关于如何正确地使用角度(https://www.dev6.com/Angular2-Conditional-Validation-with-Reactive-Formshttps://dzone.com/articles/how-to-do-conditional-validation-on-valuechanges-m)中的反应形式进行条件形式验证的文章 .

我还以为我已经弄明白了这两个问题:https://github.com/angular/angular/issues/13200 https://github.com/angular/angular/issues/14542(stackblitz链接中的第161行),但这也没有帮助 .

它似乎与点击事件后发生的变化检测有关(我理解在事件,异步事件等过程中发生检测)或 valueChanges 订阅不能在兄弟组件之间准确更新,直到焦点发生变化 . 我推测 updateValueAndValidity() 会触发变化检测,但它似乎没有 .

任何帮助都会很棒!

1 回答

  • 0

    我已经分解了您的示例代码并进行了一些更改以解决问题,现在它可以正常工作,根据您的需要 . 如果您浏览stackblitz link并单击'Veterinarian'复选框,则需要State字段 . 一旦取消,则不需要State字段 .

    我使用“@ rxweb / reactive-form-validators”进行条件验证 .

    我做了哪些更改,请参阅以下步骤:

    • 我使用了RxFormBuilder服务而不是直接创建FormGroup对象 . 行号:58至62 .
    // your old code start
            //let form = new FormGroup({
            // your old code end
            // new changed code
            let form = this.formBuilder.group({
    

    2.在StateLicense属性中,您将分配FormControl对象 . 我删除了FormControl对象并以其他方式分配值和验证器 . 我还为条件验证添加了'RxwebValidators.required',因为角度验证器不提供条件验证 . 请参阅以下代码(第125至127行):

    //# Your Old Code 
                //stateLicense: new FormControl(undefined, { validators: [Validators.maxLength(35)] }),
                //#Changed Code
                stateLicense: [undefined, [Validators.maxLength(35),RxwebValidators.required({conditionalExpression:(x) => x.veterinarian == true })]],
    
    • 我已经删除了兽医属性FormControl对象并指定了空白值 . 请参阅以下代码(第141至143行):
    //Your Code
                //veterinarian: new FormControl(),
                //#Changed Code
                veterinarian: [''],
    

    4.删除了changeDetection:ChangeDetectionStrategy.OnPush .

    总的来说,我可以说,这可以通过rxweb required conditional validator来实现 .

    如果您有任何疑问,请告诉我 .

相关问题