#angular #validation
Вопрос:
У меня есть такая структура, как эта:
<form #myForm="ngForm">
<div class=row>
<app-section-a [myForm]="myForm"></app-section-a>
и мой детский компонент:
@Component({
...
viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
// ...
@Input() myForm: ElementRef;
<input ...>
<button type=submit [disabled]="!myForm.valid">
и это прекрасно работает для обеспечения того, чтобы все компоненты в форме были учтены на предмет действительности. Дело в том, что я не думаю, что мне нужно передавать ссылку на ngForm непосредственно в качестве входных данных. Как мне пропустить этот ввод и все равно заставить это работать?
деталь: оказывается, это проект angular 5.
Комментарии:
1. если вы пытаетесь создать подформу, я бы рекомендовал проверить github.com/cloudnc/ngx-sub-form и эта статья dev.to/maxime1992/…
2. Я имею в виду, что это уже сделано. Мне просто нужна эта оптимизация
3. передача формы в качестве входных данных, на мой взгляд, прекрасна. Но вы не должны использовать
ElementRef
—> передатьFormGroup
4. @Riscie, мне нужны только свойства элемента, такие как действительность .. если я создам группу форм, разве мне не придется применять это во всех дочерних компонентах? Я определенно не хочу всего этого делать. Причина, по которой я вообще не хочу передавать ссылку, заключается в том, что она добавляет ненужную сложность всем дочерним компонентам. Я хочу, чтобы в дизайне было меньше технических долгов.
5. Я согласен с @Riscie, предпочтительнее передать группу форм. Или, если вам нужна только действительность, почему бы вам просто не передать
valid
значение, а не всю группу форм
Ответ №1:
Полный рабочий пример приведен по этой ссылке на StackBlitz.
Прежде всего, вам вообще не нужно переходить ngForm
к дочернему компоненту. Потому что вы можете определить, что дочерний компонент является частью родительской группы форм, используя ControlContainer
NgForm
массив поставщиков дочерних компонентов и предоставляя его.
В этом примере один родительский компонент app.component
загружает дочерний компонент, *ngFor
и мы только что добавили ControlContainer
в массив поставщиков дочерний компонент. Здесь нам просто нужно динамически присваивать разные имена каждому дочернему компоненту, для этого нам нужно передать индекс как @Input()
дочернему компоненту и присвоить его name
свойству InputField.
Если какой-либо из inputControl имеет ошибку, то submit
кнопка родительского контроля отключена.
app.component.html есть…
<form #heroForm="ngForm" class="container">
<div id="parent" *ngFor="let i of [0,1,2]" >
<app-child [id]="i 1" [name]="i 1" ></app-child>
</div>
<hr>
{{heroForm.value | json}}
<hr>
<div>
<app-button-submit></app-button-submit>
</div>
</form>
app-button-submit.html
<button type="submit" class="btn btn-success"
[disabled]="!control.form.valid">Submit</button>
Мы привязываемся ControlContainer
непосредственно к [disabled]
состоянию кнопки с помощью инъекции зависимостей.. смотрите constructor()
файл класса ниже.
приложение-кнопка-отправить.ts
import {ControlContainer, NgForm} from '@angular/forms';
@Component({
selector: 'app-button-submit',
templateUrl: './button-submit.component.html',
styleUrls: ['./button-submit.component.css'],
providers : [{provide : ControlContainer, useExisting : NgForm}]
})
export class ButtonSubmitComponent {
constructor(private control : NgForm) { }
}
child-component.html
<div class="form-group" >
<label [for]="Name">Name</label>
<input type="text" class="form-control" [id]="id" required [(ngModel)]="vname" [name]="Name" #names="ngModel">
{{vname}}
<div [hidden]="names.valid || names.pristine" class="alert alert-danger">
Name is required
</div>
</div>
дочерний компонент.ts
import {ControlContainer, NgForm} from '@angular/forms';
@Component({
---,
viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class ChildComponent implements OnInit {
@Input('id') id;
@Input ('name') Name;
}
здесь ControlContainer
мы позаботимся о привязке NgForm
Родительского компонента к Дочернему компоненту.
Комментарии:
1. Спасибо. Мне нравится твое мышление… но для этих целей кнопка отправки должна находиться в дочернем компоненте, а не в родительском
2. Хорошо. stackblitz.com/edit/… Ознакомьтесь с этой обновленной ссылкой
3.
constructor(private control : NgForm) { }
эта одна строка-все, что мне было нужно (хотя, вероятно, она должна быть публичной). Но я действительно ценю, насколько основателен ваш ответ, отличный ответ!4. Рад!! Ответ полезен для вас.