Як запустити валідатори форм у Angular2


82

У angular2 я хочу запустити перевірки для деяких елементів керування, коли інший елемент керування змінюється. Чи є спосіб, яким я можу просто сказати формі повторно перевірити? А ще краще, чи можу я запитати перевірку певних полів?

Приклад: Дано прапорець X та вхід P. Вхід P має валідатор, який поводиться по-різному, залежно від значення моделі X. Коли X встановлено / знято прапорець, мені потрібно викликати валідатор на P. Валідатор на P буде дивитись на модель для визначити стан X і відповідно перевірити P.

Ось деякий код:

constructor(builder: FormBuilder) {
    this.formData = { num: '', checkbox: false };

    this.formGp = builder.group({
        numberFld: [this.formData.num, myValidators.numericRange],
        checkboxFld: [this.formData.checkbox],
    });
}

this.formGp.controls['checkboxFld'].valueChanges.observer({
    next: (value) => {
        // I want to be able to do something like the following line:
        this.formGp.controls['numberFld'].validator(this.formGp.controls['numberFld']);
    }
});

У когось є рішення? Дякую!


Ви просто намагаєтесь увімкнути / вимкнути перевірку на основі значення X? Який тип валідаторів ви використовуєте? Ви можете змусити валідатори виконуватися на основі умови у вашому обсязі, але я не впевнений, що такий підхід буде працювати для вас. Див: stackoverflow.com/questions/21370006 / ...
stephen.vakil

@ stephen.vakil - Я використовую angular2.
Bonneville

@Bonneville, не могли б ви пояснити, як ви передаєте стан прапорця функції валідатора?
Варун Муллолі

Відповіді:


79

Я не знаю, чи все ще ви шукаєте відповіді, тож ось мої пропозиції:

Погляньте на це: Angular 2 - AbstractControl

Я думаю, що ти міг би зробити наступне:

this.formGp.controls['checkboxFld'].valueChanges.observer({
    next: (value) => {
       this.formGp.controls['numberFld'].updateValueAndValidity();
    }
});

Це повинно запускати та запускати валідатори. Крім того, держава також оновлюється. Тепер ви зможете ознайомитись із значенням прапорця в логіці валідатора.

Сподіваюся, це допомагає!

EDIT: оновлене посилання та приклад. Код змінився під час написання відповіді.

EDIT_2: alpha.48 змінює EventEmitter.observer на EventEmitter.subscribe!

EDIT_3: Змінено посилання на фактичну реалізацію, додано посилання на документи

Валідатон-путівник

Документація FormControl


Дякую @Nightking за пропозицію, я спробую. Зверніть увагу, що ваше посилання не працює.
Бонневіль,

@Bonneville Дякую за інформацію. Вони витягли код форми у загальний простір імен. Речі дещо змінюються на швидкі :). Я оновив посилання на джерело.
Найкінг

Нарешті я дійшов до використання цього фрагмента коду, і, здається, це працює для мене. Дякую! До речі, у вашому коді є помилка: у функції updateValueAndValidity () відсутня буква "e". Ваш код оновлено замість оновлення. Вітаємо, це було великою допомогою!
Bonneville

1
Посилання порушено; може бути оновлено до github.com/angular/angular/blob/master/packages/forms/src/…, хоча не зовсім однаково. Можна також посилатися на Angular docs
Вибухові таблетки

1
Рятувальник життя !! Я застряг у випадку використання, коли користувач надсилає форму, не торкаючись жодного елемента управління. Форма недійсна, але елементи керування не відображають жодного повідомлення про помилку
pravin

42

з моєю ControlGroup я роблю це, оскільки у мене є помилки divs, які перевіряють, чи торкнулися їх

for (var i in this.form.controls) {
  this.form.controls[i].markAsTouched();
}

(this.form - це моя ControlGroup)


це насправді правильна відповідь. Якщо потрібно одноразове введення, this.form.controls ['name']. MarkAsTouched ();
chris_r



6

Існують більш елегантні способи моделювання такої поведінки - наприклад, введення вашого стану в ReplaySubject і спостереження за цим, а потім використання асинхронних валідаторів для спостереження за станом - але псевдокодований підхід нижче повинен спрацювати. Ви просто спостерігаєте за змінами значень у прапорці, оновлюєте модель відповідно, а потім примусово повторно перевіряєте числоFld за допомогою cal. UpdateValueAndValidity.

constructor(builder: FormBuilder) {
  this.formData = { num: '', checkbox: false };
  const numberFld = builder.control(this.formData.num, myValidators.numericRange);

  const checkbox = builder.control(this.formData.checkbox);
  checkbox.valueChanges.map(mapToBoolean).subscribe((bool) => {
    this.formData.checked = bool;
    numberFld.updateValueAndValidity(); //triggers numberFld validation
  });

  this.formGp = builder.group({
      numberFld: numberFld,
      checkboxFld: checkbox
  });
}

0
static minMaxRange(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        if (Validators.min(min)(control)) { // if min not valid
            return Validators.min(min)(control);
        } else {
            return Validators.max(max)(control);
        }
    };
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.