Проверка «Требуется» не работает с radiobtn при использовании ngFor в реактивных формах

У меня есть динамическая реактивная угловая форма, которая создает формы и динамически заполняет внутри нее вопросы в соответствии с типами вопросов, полученными из базы данных. проблема в том, что требуемая проверка (встроенная проверка HTML5 ngNativeValidate) не работает, когда я добавляю ее внутри цикла * ngFor.

в моем конструкторе форм у меня есть эта часть

<div class = "row" *ngSwitchCase = "'radiobtn'">
      <legend class = "col-form-label col-sm-6 pt-0">{{question.label}}</legend>
      <div class = "col-sm-6">
        <div class = "form-check" *ngFor = "let opt of question.options; let i = index">
          <label class = "form-check-label" [attr.for] = "question.key+opt.key">
          <input class = "form-check-input" type = "radio" [name] = "question.key" [formControlName] = "question.key"
[id] = "question.key+opt.key" [value] = "opt.key" required />
            {{opt.value}}
          </label>
        </div>
      </div>
    </div>

У меня есть ngNativeValidate в теге формы и new FormControl(question.value || '', Validators.required) в конструкторе FormGroup.

Предполагается, что этот код применяет необходимую проверку проверки, но он не работает. когда я удаляю цикл for и делаю его статическим, проверка работает. в чем здесь причина.

Примечание: моя версия Angular — 10.

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

Naren Murali 25.07.2024 12:11

@NarenMurali, вы сказали, что я смешиваю формы, управляемые шаблонами, и реактивные формы, потому что у меня есть и formControlName, и ngModel? да, но даже когда я удаляю ngModel, он все равно не работает. Я отредактирую свой вопрос, чтобы избежать конфликтов

Mohammad AM 25.07.2024 12:19

Да, но для проверки требуется stackblitz, это тоже может быть ошибка, но нужно проверить

Naren Murali 25.07.2024 12:21

что-то вроде этого ссылка stackblitz

Mohammad AM 25.07.2024 16:38
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
1
4
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

При работе с native validations всегда отдавайте предпочтение Формам на основе шаблонов, потому что если вы выберете шаблон на основе шаблона, добавленная вами проверка не будет запускать собственные проверки HTML.

HTML:

<div class = "jumbotron text-center">
  <h1 class = "display-5">Radio Buttons in Angular</h1>
</div>

<div class = "container">
  <div class = "row custom-wrapper">
    <div class = "col-md-12">
      <!-- Form starts -->
      <form (ngSubmit) = "onSubmit()" #actorForm = "ngForm" ngNativeValidate>
        <!-- Gender -->
        <div class = "group-gap">
          <h5 class = "mb-3">Gender</h5>
          <div class = "d-block my-3">
            <div *ngFor = "let gender of questions[0].genders; let i = index">
              <label [for] = "gender">
                <input
                  type = "radio"
                  name = "gender"
                  [id] = "gender"
                  [(ngModel)] = "genderVal"
                  [value] = "gender"
                  required
                />
                {{ gender }}
              </label>
            </div>
          </div>
        </div>

        <!-- Submit Button -->
        <button type = "submit" class = "btn btn-danger btn-lg btn-block">
          Submit
        </button>
      </form>
      <!-- Form ends -->
    </div>
  </div>
</div>

ТС:

import { Component, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  @ViewChild('actorForm') registrationForm: NgForm;
  isSubmitted = false;
  questions: { genders: string[] }[] = [{ genders: ['Male', 'Female'] }];
  genderVal = '';

  // Submit Registration Form
  onSubmit() {
    this.isSubmitted = true;
    alert(JSON.stringify(this.registrationForm.valid));
    if (!this.registrationForm.valid) {
      return false;
    } else {
      alert(JSON.stringify(this.registrationForm.value));
    }
  }
}

Демо-версия Stackblitz

Но вот пример реактивных форм, вот что вам нужно знать.

Когда вы добавляете проверку, соответствующая директива также должна присутствовать в HTML, поэтому у нас есть обязательный атрибут.

HTML:

<div class = "jumbotron text-center">
  <h1 class = "display-5">Radio Buttons in Angular</h1>
</div>

<div class = "container">
  <div class = "row custom-wrapper">
    <div class = "col-md-12">
      <!-- Form starts -->
      <form
        [formGroup] = "registrationForm"
        (ngSubmit) = "onSubmit()"
        ngNativeValidate
      >
        <!-- Gender -->
        <div class = "group-gap">
          <h5 class = "mb-3">Gender</h5>
          <div class = "d-block my-3">
            <div *ngFor = "let gender of questions[0].genders; let i = index">
              <label [for] = "gender">
                <input
                  type = "radio"
                  name = "gender"
                  [id] = "gender"
                  formControlName = "gender"
                  [value] = "gender"
                  required
                />
                {{ gender }}
              </label>
            </div>
          </div>
        </div>

        <!-- Submit Button -->
        <button type = "submit" class = "btn btn-danger btn-lg btn-block">
          Submit
        </button>
      </form>
      <!-- Form ends -->
    </div>
  </div>
</div>

ТС:

import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  isSubmitted = false;
  questions: { genders: string[] }[] = [{ genders: ['Male', 'Female'] }];

  constructor(public fb: FormBuilder) {}

  /*########### Form ###########*/
  registrationForm = this.fb.group({
    gender: ['', [Validators.required]],
  });

  // Submit Registration Form
  onSubmit() {
    this.isSubmitted = true;
    alert(JSON.stringify(this.registrationForm.valid));
    if (!this.registrationForm.valid) {
      return false;
    } else {
      alert(JSON.stringify(this.registrationForm.value));
    }
  }
}

Демо-версия Stackblitz

Вот мой исходный код, который не работает [ссылка]stackblitz.com/edit/…

Mohammad AM 25.07.2024 18:21

@MohammadAM В своем ответе я поделился решением для шаблонного и реактивного решения, пожалуйста, просмотрите его и дайте мне знать, если возникнут какие-либо сомнения.

Naren Murali 25.07.2024 18:48

Да, ваш пример отлично работает с реактивными формами, но он перестает работать, когда я начинаю динамически связывать атрибуты name и formControlName. вы можете увидеть это в моем обновленном коде здесь [stackblitz.com/edit/…

Mohammad AM 28.07.2024 09:06

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

Naren Murali 28.07.2024 09:29

да, они совпадают [name] = "question.key"[formControlName] = "question.key" и вот код TS `group[question.key] = new FormControl(question.value || '', Validators.required); ` но все еще не работает

Mohammad AM 28.07.2024 10:10

@MohammadAM Спасибо за ваше терпение, это похоже на ошибку, не стесняйтесь поднимать проблему с github на официальной странице angular на github.

Naren Murali 28.07.2024 15:02

не беспокойтесь и спасибо за вашу помощь. только что опубликовал проблему на странице Angular на github

Mohammad AM 28.07.2024 16:01
Ответ принят как подходящий

Для input[radio] должны быть установлены как [name], так и [attr.name].

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