Пользовательский угловой валидатор с параметрами запускается только один раз

#angular #angular-reactive-forms

#угловой #угловые реактивные формы

Вопрос:

У меня есть пользовательский валидатор с параметрами, установленными на FormGroup , и он запускается один раз при инициализации, но не запускается ни при одном из изменений элемента управления. Удаление параметров запускает валидатор при каждом изменении элемента управления, но, очевидно, не работает без параметров. Есть предложения по запуску этого при каждом изменении элемента управления? Я пытался наблюдать за элементами управления и использовать updateValueAndValidity() и все еще безуспешно.

 const customValidator = (options: { min: number, max: number }): ValidatorFn => {
  console.log(options);
  return (control: AbstractControl): { [key: string]: boolean } | null => {
    // logic returning null or { 'not-enough': true }
  }
}
    
this.form = new FormGroup({
  controlOne: new FormControl(null),
  controlTwo: new FormControl(null)
}, { validators: [customValidator({min: 5, max: 10})]});
  

Найдено решение

Благодаря комментариям ниже и другим ответам я понял, что моя консоль регистрируется снаружи для функции возврата валидатора, запускаемой только один раз. Перемещение этой и любой другой дополнительной логики внутри возвращаемой функции выполняется, как и ожидалось. В конечном итоге мое решение состояло в том, чтобы просто переместить некоторый код вниз по строке…

 const customValidator = (options: { min: number, max: number }): ValidatorFn => {
  // No code up here will run on each control being validated
  return (control: AbstractControl): { [key: string]: boolean } | null => {
    // code down here will run on every control change
    // logic returning null or { 'not-enough': true }
  }
}
    
this.form = new FormGroup({
  controlOne: new FormControl(null),
  controlTwo: new FormControl(null)
}, { validators: [customValidator({min: 5, max: 10})]});
  

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

1. какие-либо ошибки в вашей консоли?

2. В консоли нет ошибок. Проблема в том, что валидатор запускается только один раз при создании экземпляра формы. Я собираюсь запускать валидатор в любое время, когда изменяется элемент управления в группе форм.

3. Кажется, в этой демонстрации все работает просто отлично: stackblitz.com/edit/angular-form-custom-validation-gcbyvt . Вы делаете что-то другое?

4. Да, спасибо, я нашел проблему. У меня была некоторая объектная деструктуризация options параметров, приведенных выше return , вместе с журналами моей консоли. Я вижу, что завод запускается один раз, но валидатор — это все, что есть в возвращаемой функции. Я переместил свою логику внутрь функции возврата, и теперь все работает.

Ответ №1:

У вас должна быть ошибка в консоли, потому что вы ничего не возвращаете в своем ValidatorFn :

ОШИБКА в src / app / app.component.ts(13,44): ошибка TS2355: функция, объявленный тип которой не является ни ‘void’, ни ‘any’, должна возвращать значение.

Шаблон

  1. Обязательно привяжите FormGroup к форме
  2. Обязательно свяжите каждый FormControl

Код

 <div style="text-align:center">
  <form [formGroup]="form">
      <input type="text" formControlName="controlOne">
      <input type="submit">
  </form>
</div>
  

Модуль

  1. обязательно импортируйте ReactiveFormsModule

Код

 import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
  

Контроллер

  1. импорт FormControl, FormGroup, AbstractControl, ValidatorFn
  2. возврат из ValidatorFn

Код

 import { Component } from '@angular/core';
import { FormControl, FormGroup, AbstractControl, ValidatorFn } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
    customValidator = (options: { min: number, max: number }): ValidatorFn => {
        return (control: AbstractControl): { [key: string]: boolean } | null => {
            console.log(options.min, options.max);
            return {};//RETURN ERRORS HERE
        }
    }

    form = new FormGroup({
        controlOne: new FormControl(null)
    }, { validators: [this.customValidator({min: 5, max: 10})]});
}
  

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

1. Тогда я не уверен, что понимаю ваш вопрос. Этот валидатор запускается всякий раз, когда изменяются элементы управления в FormGroup . Разве это не предполагаемая функциональность?

2. ValidatorFnFactory, конечно, будет запущен только один раз, если это то, что вы имеете в виду.

3. Есть предложения по запуску этого при каждом изменении элемента управления? Возможно, я не понимаю, что это такое. Речь идет о пользовательской фабрике валидатора или о валидаторе, возвращенном из нее? Последнее уже работает, поэтому вы, должно быть, имеете в виду первое… Это правильно?

4. Это правильно. customValidator Функция на самом деле является заводской функцией. Когда вы вызывали его с помощью customValidator({min: 5, max: 10}) , он вернул ValidatorFn . Все, что находится в возвращаемом ValidatorFn, будет выполняться при каждом изменении FormControl.

5. Большое спасибо, я отредактировал вопрос, чтобы также включить эти примечания для будущих зрителей.