Javascript Angular 2:在 valueChanges 之后更新 FormControl 验证器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39897975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:02:29  来源:igfitidea点击:

Angular 2: Update FormControl validator after valueChanges

javascriptangulartypescript

提问by Markus T?r?k

Is there a way to update the Validtorsof a FormControl Object? I have FormGroupwhere one Input is a select field, when the value of the select field changes I want the other FormControl in my FormGroup to change the validator.

有没有办法更新ValidtorsFormControl 对象的?I have FormGroupwhere one Input is a select field, when the value of the select field changes I want the other FormControl in my FormGroup to change the validator.

Here is my subscribeToFormChanges()method from my FormGroup component:

这是我的subscribeToFormChanges()FormGroup 组件中的方法:

private appIdRegexes = {
    ios: /^[a-zA-Z][a-zA-Z0-9]*(\.[a-zA-Z0-9\-]+){2,}$/,
    android: /^([a-zA-Z])[a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9\-]*){2,}$/,
    any: /^any$/
  };

private subscribeToFormChanges(): void {
    const myFormValueChanges$ = this.appsForm.valueChanges;
    myFormValueChanges$.subscribe(x => {
      const platform = this.appsForm.controls['platform'].value;
      const appId = this.appsForm.controls['appId'].value;

      if (this.appIdRegexes[platform]) {
        this.appsForm.controls['appId'] = new FormControl(appId, Validators.pattern(this.appIdRegexes[platform].source));
      }
    });
  }

And here's the html template:

这是 html 模板:

<div class="row" [formGroup]="appsForm">
  <div class="form-group col-xs-6">
    <label>Platform</label>

    <select id="licensePlatform" class="form-control"
            formControlName="platform">
      <option *ngFor="let platform of licensePlatforms" [value]="platform">
        {{platform}}
      </option>
    </select>

    <small [hidden]="appsForm.controls.platform.valid">
      Platform is required
    </small>
  </div>

  <div class="form-goup col-xs-6">
    <label>App ID</label>
    <input type="text" class="form-control" formControlName="appId">
    <small [hidden]="appsForm.controls.appId.valid">
      Please use the right ID format
    </small>
  </div>
</div>

When I'm implementing the subscribeToFormChanges()method like shown here, appsForm.controls.appId.valuedoesn't update anymore when writing into the input field. Initially the value is updating.

当我实现subscribeToFormChanges()这里显示的方法appsForm.controls.appId.value时,写入输入字段时不再更新。最初该值正在更新。

回答by Markus T?r?k

I solved the issue by listening to valueChangeson my platform select field and then I use the setValidators()method on the appId input field. This articlewas quite helpful.

我通过valueChanges在我的平台选择字段上收听解决了这个问题,然后我setValidators()在 appId 输入字段上使用了该方法。这篇文章很有帮助。

Here's my solution:

这是我的解决方案:

 private subscribePlatformChanges() {
    const platformCtrl = this.appsForm.controls['platform'];
    const changes$ = platformCtrl.valueChanges;

    changes$.subscribe(platform => {
      this.appsForm.controls['appId'].setValidators([Validators.pattern(this.appIdRegexes[platform].source),
                                                    Validators.required]);
      this.appsForm.controls['appId'].updateValueAndValidity();
    });
  }

回答by Poul Kruijt

To recheck the controls within a FormGroup, you can do something with the updateValueAndValidityof the FormControl.

重新检查内部的控件FormGroup,你可以做的事情updateValueAndValidityFormControl

If this.appsFormis indeed a FormGroup:

如果this.appsForm确实是一个FormGroup

this.appsForm.controls.forEach(control => control.updateValueAndValidity());

回答by znwz

you can fire a change event from the select as below

您可以从选择中触发更改事件,如下所示

<select id="licensePlatform" class="form-control"
            formControlName="platform"  (change)="update($event.target.value)" >
      <option selected="selected" disabled="disabled" value="">Select Card Type</option>
      <option *ngFor="let platform of licensePlatforms" [value]="platform" >
        {{platform}}
      </option>
    </select>

And in the component you can write the update function as below

在组件中,您可以编写如下更新函数

update(value){
      if(value){
        (<FormControl>this.appsForm.controls['platform']).setValue(value, {onlySelf: false});
        const appId = this.appsForm.controls['appId'].value;
        if (this.appIdRegexes[value]) {
        this.appsForm.controls['appId'] = new FormControl(appId, Validators.pattern(this.appIdRegexes[value].source));
      }
    };

  }

This will update the validator according to the choice you make in the dropdown. I believe this will resolve your issue.

这将根据您在下拉列表中所做的选择更新验证器。我相信这将解决您的问题。