Кутовий 2: Ітерація над елементами управління з реактивною формою


Відповіді:


198

З'ясував, що Object.keysз цим впорається ..

    Object.keys(this.form.controls).forEach(key => {
      this.form.get(key).markAsDirty();
    });

Для Angular 8+ використовуйте наступне (на основі відповіді Мікеланджело):

    Object.keys(this.form.controls).forEach(key => {
      this.form.controls[key].markAsDirty();
    });

2
Коли я використовую цю функцію в onSubmit, я отримую повідомлення про помилку. Хтось Cannot invoke an expression whose type lacks a call signature. Type 'AbstractControl' has no compatible call signatures.знає, чому?
maidi

1
Object.keys (this.registerForm.controls) .forEach (key => {this.registerForm.controls [key] .markAsDirty ();});
Foad

Коли я пробую Object.keys або навіть "за", я нічого не отримую. Однак, якщо я console.log (form.controls), я бачу всі різні елементи керування формою, що містяться в об'єкті. Я збентежений.
Джейк Шексворт,

Використовуючи Angular 5, markAsDirty () / markAsTouched () не повторюється в жодну підгрупу форм. Я розбив код вище на рекурсивну функцію і викликаю його на будь-якій підгрупі FormGroups. Працює краще із поточним проектом інтерфейсу Angular Material, якщо користувач ніколи не торкається потрібного елемента, я називаю це, коли користувач намагається надіслати форму, щоб позначити будь-яку на той момент.
Роберт

3
Thnx за читання мого повідомлення та оновлення власної відповіді. Офіційні документи також застарілі, тому мені довелося це зрозуміти, надрукувавши кожен рядок ...
Мікеланджело,

56

Для того, що варто, є інший спосіб зробити це, не використовуючи магію Object.keys (...) :

for (const field in this.form.controls) { // 'field' is a string

  const control = this.form.get(field); // 'control' is a FormControl  

}

як отримати індекс циклу?
СВК

1
Для тих, хто використовує TSLint, код працює, але TSLint скаржиться на "для (... в ...) оператори повинні бути відфільтровані за допомогою оператора if (forin)".
Єннефер

1
tslint спрямована назовні, цитата з документації JavaScript протягом ... в заяві stackoverflow.com/questions/40770425 / ...
Егле Kreivyte

41

Прийнята відповідь є правильною для плоскої структури, але не повністю відповідає на вихідне запитання. Для веб-сторінки можуть знадобитися вкладені FormGroups та FormArrays, і ми повинні врахувати це, щоб створити надійне рішення.

public markControlsDirty(group: FormGroup | FormArray): void {
    Object.keys(group.controls).forEach((key: string) => {
        const abstractControl = group.controls[key];

        if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) {
            this.markControlsDirty(abstractControl);
        } else {
            abstractControl.markAsDirty();
        }
    });
}

буде instanceofзавжди працювати після того , як transpiled по машинопису?
помітний

@ the-notable instanceofне є специфічним для TypeScript ключовим словом ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ), а також не є classтипом даних.
Кінан Діггс

7

Використовуючи відповідь @Marcos, я створив функцію, яку можна назвати передачею formGroup як параметра, і вона позначає кожну форму дочірньої форми formGroup брудною, просто для того, щоб зробити її придатною для використання з інших місць навколо коду, поміщаючи її всередину служби, наприклад.

public touchAllFormFields(formGroup: FormGroup): void {
    Object.keys(formGroup.controls).forEach((key) => {
        formGroup.get(key).markAsDirty();
    });
}

сподіваюся, це допоможе;)


Ідеально! Додано в службу разом із подібними функціями для clearValidators, unouch тощо. Можливо, хочеться додати рекурсивну перевірку для вкладених елементів керування, але це працює наразі. Дякую!
mc01

6

Здається, ця get функція вже не працює для отримання конкретних значень у вашій формі в Angular 8, тож ось як я це вирішив на основі відповіді @Liviu Ilea.

for (const field in this.myForm.controls) { // 'field' is a string
  console.log(this.myForm.controls[field].value);
}

Ти впевнений? API doc вже має метод get для абстрактного контролю ( angular.io/api/forms/AbstractControl#get ). Я ще не мігрував. Зараз я боюся (⊙_ ◎)
Алан

@AlanGrosz Так, я це теж бачив, коли переписував, але навіть при друку всіх рядків у консолі я не міг знайти жодного методу get на об'єкті. Я думаю, що документація позаду. Удачі при міграції!
Мікеланджело

Я не думаю, що вони його видалили, отримайте для мене роботи в Angular 8. Також це все ще є в документації angular.io/api/forms/AbstractControl#get
Ласло Сарвольд


3

Це те, що працює для мене

private markFormGroupTouched(formGroup: FormGroup) {
  Object.keys(formGroup.controls).forEach((key) => {
    const control = formGroup.controls[key];
    control.markAsDirty();
    if ((control instanceof FormGroup)) {
      this.markFormGroupTouched(control);
    }
  });
}

1

Я створюю цю функцію, щоб зробити це * У мене є елемент керування з ім'ям 'порядок', і передаю йому індекс.

{"conditionGroups": [
   {
     "order": null,
     "conditions": []
   }
  ]
}


updateFormData() {
    const control = <FormArray>this.form.controls['conditionGroups'];  
    control.value.map((x,index)=>{
    x.order = index; 
 })
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.