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

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

const customValidator = (options: { min: number, max: number }): ValidatorFn => {
  console.info(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})]});

какие-нибудь ошибки в вашей консоли?

pixelbits 07.04.2019 06:22

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

mrtpain 07.04.2019 22:09

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

pixelbits 07.04.2019 22:26

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

mrtpain 08.04.2019 00:38
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
4
4
1 610
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

ERROR in src/app/app.component.ts(13,44): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.

Шаблон

  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.info(options.min, options.max);
            return {};//RETURN ERRORS HERE
        }
    }

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

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

mrtpain 07.04.2019 18:25

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

Rafael 07.04.2019 20:38

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

Rafael 07.04.2019 20:39
Любые предложения по запуску этого при каждом изменении элемента управления? Возможно, я не понимаю, что такое это. Речь идет о кастомной фабрике валидаторов или о валидаторе, возвращенном из нее? Последнее уже работает, так что вы, должно быть, имеете в виду первое... Верно?
Rafael 07.04.2019 20:56

Я исходил из того, что функция customValidator будет запускаться каждый раз, когда элемент управления в группе формы изменяется либо возвращая ошибку, либо ноль. Разве это не так? Я впервые пишу собственный валидатор, поэтому, возможно, я что-то упустил.

mrtpain 07.04.2019 22:06

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

mrtpain 08.04.2019 00:39

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

Rafael 08.04.2019 00:43

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

mrtpain 08.04.2019 00:44

Вы должны признать, что ваш первоначальный комментарий к моему ответу был неверным. Предоставленный мной console.info применяется к изменению каждый. Решение, которое я вам предоставил, было правильным и полным.

Rafael 08.04.2019 00:55

Другие вопросы по теме

Компонент дочерней формы не извлекает данные формы по умолчанию родительского компонента
Новые пользователи реактивных форм. TypeError: Невозможно прочитать свойство firstName неопределенного
Angular 7: как установить значение по умолчанию для выбора коврика в реактивной форме, когда значение представляет собой объект с несколькими идентификаторами, а не с одним идентификатором?
Я хочу отображать данные во втором поле выбора, когда я выбираю первое поле выбора из данных json URL-адреса API
Скопируйте динамические значения FormGroup в класс данных в Angular [Reactive Forms]
Как исправить: проверка формы Angular 7 (шаблон SmartAdmin) перестает работать после навигации
Почему флажок не работает должным образом в Angular, когда я передаю тип со скобкой?
Изменения значений не вызываются в реактивной форме с использованием Angular6
Angular: обнаруживать только те FormControls, которые изменились
Как установить значение динамических каскадных выпадающих списков в angular?