Angular 2: обновление валидатора FormControl после valueChanges

#javascript #angular #typescript

#javascript #angular #typescript

Вопрос:

Есть ли способ обновить Validtors объект FormControl? У меня есть FormGroup место, где один вход является полем выбора, когда значение поля выбора изменяется, я хочу, чтобы другой FormControl в моей FormGroup изменил валидатор.

Вот мой 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));
      }
    });
  }
  

И вот шаблон 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>
  

Когда я реализую subscribeToFormChanges() метод, подобный показанному здесь, appsForm.controls.appId.value он больше не обновляется при записи в поле ввода. Изначально значение обновляется.

Комментарии:

1. Используйте значение исправления для обновления формы this.form.patchValue({controlTobeUpdated:value}); angular.io/docs/ts/latest/api/forms/index /…

2. @user32 но patchValue() позволяет мне обновлять только значение, а не валидатор?

3. Правильно. patchValue() позволяет обновлять значение, но как только это значение будет обновлено, будут запущены валидаторы обновлений.

4. теперь я понимаю вашу проблему, я предлагал что-то еще.

Ответ №1:

Я решил проблему, прослушав valueChanges поле выбора моей платформы, а затем я использую setValidators() метод в поле ввода AppID. Эта статья была весьма полезной.

Вот мое решение:

  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();
    });
  }
  

Комментарии:

1. В следующей статье показано 3 способа достижения того же: netbasal.com /…

Ответ №2:

Чтобы перепроверить элементы управления внутри a FormGroup , вы можете что-то сделать с updateValueAndValidity FormControl помощью .

Если this.appsForm действительно FormGroup :

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

Комментарии:

1. Я думаю, что это обновляет только статус проверки, но не шаблон регулярных выражений валидатора?

Ответ №3:

вы можете запустить событие изменения из выбора, как показано ниже

 <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>
  

И в компоненте вы можете написать функцию обновления, как показано ниже

 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));
      }
    };

  }
  

Это обновит валидатор в соответствии с выбором, который вы делаете в раскрывающемся списке.
Я считаю, что это решит вашу проблему.