Angular FormArray - ›FormGroup -› FormControls: почему валидация всплывает от элемента управления к массиву и почему каждый элемент управления занимает отдельную строку?

Изображение:

введите описание изображения здесь

Код:

Контроллер TS:

this.formTest = this.formBuilder.group({
    first: ['', Validators.required],
    firsttwo: [''],
    second: this.formBuilder.array([this.formBuilder.group(
        {
            one: ['', Validators.required],
            two: [false],
            three: [false],
            four: []
        })
    ])
});

HTML:

<form [formGroup]="formTest" (ngSubmit)="onLogSubmit()">
    <div class="row">
        <div class="form-group col-6 col-md-2">
            <label for="first">First*</label>
            <div [ngClass]="{'has-error': (formTest.controls.first.errors && formTest.controls.first.dirty), 'has-success': !formTest.controls.first.errors}">
                <input type="number" name="first" min="1" class="form-control" autocomplete="off" placeholder="Nro" formControlName="first" required />
                <!-- Validation -->
                <ul class="help-block">
                    <li *ngIf="formTest.controls.first.errors?.required && formTest.controls.first.dirty">Pakollinen kenttä</li>
                </ul>
            </div>
        </div>
        <div class="form-group col-6 col-md-2">
            <label for="firsttwo">FirstTwo*</label>
            <input type="number" name="firsttwo" min="1" class="form-control" autocomplete="off" placeholder="Nro" formControlName="firsttwo"/>
        </div>
    </div>
    <br>
    <div class="row" formArrayName="second">
        <div class="col-12" *ngFor="let s of formTest.controls.second.controls; let i=index" [formGroup]="s">
            <div class="form-group col-6 col-md-2">
                <label>One</label>
                <input type="number" step="0.1" min="0" class="form-control" formControlName="one">
            </div>                                
            <div class="form-group col-6 col-md-2">
                <label class="form-check checkbox-container">
                    <input type="checkbox" class="form-check-input" formControlName="two">
                    <span class="checkmark"></span>
                    <label class="form-check-label" for="type">Two</label>
                </label>
            </div>
            <div class="form-group col-6 col-md-2">
                <label class="form-check checkbox-container">
                    <input type="checkbox" class="form-check-input" formControlName="three">
                    <span class="checkmark"></span>
                    <label class="form-check-label" for="deco">Three</label>
                </label>
            </div>
            <div class="form-group col-6 col-md-2">
                <label>Four</label>
                <input type="number" step="1" min="0" class="form-control" formControlName="four">
            </div>
        </div>
    </div>
    <br>
</form>

Моя проблема в следующем:

  1. Почему один Validation.required внутри FormGroup FormControl от FormArray закрашивает всю внутреннюю FormGroup красной полосой сбоку?
  2. Почему каждый элемент управления внутренней группы формы находится в отдельной строке? Загрузочная программа обычно правильно поддерживает правильное распределение столбцов, как в полях группы внешней формы?

РЕДАКТИРОВАТЬ:

  1. Решено, спасибо Элисео. Пришлось специально удалить границу как с formArrayName-div, так и с [FormGroup] -div, используя простой css-класс.

  2. Решено. По какой-то причине [FormGroup] -div нуждается в собственном классе-строке вместо класса столбца, чтобы дочерние div-элементы распознавали столбцы начальной загрузки.

Исправленная версия:

<div class="no-validation-color" formArrayName="second">
        <div class="row no-validation-color" *ngFor="let s of formTest.controls.second.controls; let i=index" [formGroup]="s">
.no-validation-color {
    border: 0px;
}

person Murre    schedule 06.07.2020    source источник


Ответы (1)


Когда элемент управления недействителен, если он находится внутри FormGroup / FormControl, FormGroup также недействительна. Если FormGroup / FormArray находится внутри другой FormGroup, последняя также недействительна. Angular еще добавляет класс ng-invalid и ng-touched. Глупый пример Создайте форму:

  form=new FormGroup({
    name:new FormControl(null,Validators.required)
  })

управление в .html

<form [formGroup]="form">
  <input formControlName="name">
</form>

Используйте этот .css

.ng-invalid
{
  border:1px solid red;
}

Вы видите, что вход имеет красную границу, но также форма имеет красную границу. Решение просто

input.ng-invalid
{
  border:1px solid red;
}

только вход теперь имеет красную границу

Что ж, нам нужна граница только в том случае, если ввод затронут и недействителен

input.ng-invalid.ng-touched
{
  border:1px solid red;
}

Другой пример, представьте, что у нас есть собственный валидатор над FormGroup. внутренние конструкции действительны, но группа formGroup недействительна. Некоторым нравится

  form=new FormGroup({
    name:new FormControl(null,Validators.required),
    group:new FormGroup({
      prop1:new FormControl(),
      prop2:new FormControl()
    },this.customValidator())
  })

  customValidator()
  {
    return (formGroup)=>{
      return !formGroup.value.prop1?{error:'error'}:null
    }
  }

Да, это глупый пример, группа недействительна, если prop1 имеет значение null или пусто

Если мы сделаем такую ​​форму, как

<form [formGroup]="form">
    <input formControlName="name">
    <div id="group1" formGroupName="group">
        <input formControlName="prop1">
        <input formControlName="prop2">
  </div>
</form>

У нас может быть .css вроде

input.ng-invalid.ng-touched
{
  border:1px solid red;
}

/*All the input inside the formGroup with id="group1" if the group1 is invalid*/
#group1.ng-invalid input.ng-touched 
{
  border: 1px solid red!important;
}
person Eliseo    schedule 06.07.2020
comment
Я могу понять недействительность родительского элемента, но зачем ему рисовать ужасный красный цвет сбоку? Он ничего не отображает в базовой FormGroup, которую я обычно использую для проверки всей формы перед ее отправкой. Просто интересно, как это реализовано по умолчанию в Angular. Но спасибо за примеры, это помогает мне от этого избавиться. Было ли у вас какое-либо понимание вопроса n. 2? - person Murre; 06.07.2020
comment
проверьте свой .css, я почти уверен, что у вас есть такие, как .ng-invalid{...}, переопределите, используя некоторые, например, #group1.ng-invalid{..} - person Eliseo; 07.07.2020