MMa*_*rio 1 angular angular-reactive-forms angular-template-form
我正在研究 Angular 10。已经 3 天了,我遇到了 Angular 模板驱动和反应式表单的问题。
我想做的:创建一个包含许多子组件的复杂表单(以便分离大量代码)。然后单击一个按钮,我想验证所有表单和子组件。我想以某种方式验证子组件。
我创建的内容:具有双向绑定的模板驱动表单,因为我相信它更容易并且对于我的情况来说不需要。
我已经设法使验证仅适用于基本表单。我无法在儿童组件上做到这一点。我看到很多关于这个问题的帖子并尝试了很多,但我很困惑。
我的代码:
mainForm.html
<div class="card m-3">
<div class="card-body">
<fieldset>
<form name="form" (ngSubmit)="f.form.valid && onSubmit()" #f="ngForm" novalidate>
<div class="form-row">
<div class="form-group col">
<label>Title</label>
<select name="title" class="form-control" [(ngModel)]="model.title" #title="ngModel" [ngClass]="{ 'is-invalid': f.submitted && title.invalid }" required>
<option value=""></option>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="Miss">Miss</option>
<option value="Ms">Ms</option>
</select>
<div *ngIf="f.submitted && title.invalid" class="invalid-feedback">
<div *ngIf="title.errors.required">Title is required</div>
</div>
</div>
<div class="form-group col-5">
<label>First Name</label>
<input type="text" name="firstName" class="form-control" [(ngModel)]="model.firstName" #firstName="ngModel" [ngClass]="{ 'is-invalid': f.submitted && firstName.invalid }" required>
<div *ngIf="f.submitted && firstName.invalid" class="invalid-feedback">
<div *ngIf="firstName.errors.required">First Name is required</div>
</div>
</div>
<div class="form-group col-5">
<label>Last Name</label>
<input type="text" name="lastName" class="form-control" [(ngModel)]="model.lastName" #lastName="ngModel" [ngClass]="{ 'is-invalid': f.submitted && lastName.invalid }" required>
<div *ngIf="f.submitted && lastName.invalid" class="invalid-feedback">
<div *ngIf="lastName.errors.required">Last Name is required</div>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label>Date of Birth</label>
<input type="date" name="dob" class="form-control" [(ngModel)]="model.dob" #dob="ngModel" [ngClass]="{ 'is-invalid': f.submitted && dob.invalid }" required pattern="^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$">
<div *ngIf="f.submitted && dob.invalid" class="invalid-feedback">
<div *ngIf="dob.errors.required">Date of Birth is required</div>
<div *ngIf="dob.errors.pattern">Date of Birth must be a valid date in the format YYYY-MM-DD</div>
</div>
</div>
</div>
> One child component for demonstration(there are more)--code continues below
<app-extra-info [(model)]="model"></app-extra-info> pass model in children
<div class="text-center">
<button class="btn btn-primary mr-1">Register</button>
</div>
</form>
</fieldset>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
子组件.html:
<div class="form-group row">
<label class="col-2 col-form-label">Gender</label>
<div class="col-4">
<select id="gender" name="gender" class="form-control" required>
<option>Male</option>
<option>Female</option>
<option>Not Specify</option>
<option></option>
</select>
</div>
</div>
<div class="form-group row">
<label>Pet name</label>
<input type="text" name="petName" class="form-control" [(ngModel)]="model.petName" #petName="ngModel" [ngClass]="{ 'is-invalid': petName.invalid && petName.dirty}" required>
<div *ngIf="petName.invalid" class="invalid-feedback">
<div *ngIf="petName.errors.required">Pet Name is required</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
儿童组件.ts:
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-extra-info',
templateUrl: './extra-info.component.html',
styleUrls: ['./extra-info.component.css']
})
export class ExtraInfoComponent implements OnInit {
@Input() model: any;
constructor() { }
ngOnInit(): void {
}
}
Run Code Online (Sandbox Code Playgroud)
父.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-user-settings-form',
templateUrl: './user-settings-form.component.html',
styleUrls: ['./user-settings-form.component.css']
})
export class UserSettingsFormComponent implements OnInit {
model: any = {};
constructor() {
}
ngOnInit() {
}
onSubmit() {
alert(JSON.stringify(this.model, null, 4));
}
Run Code Online (Sandbox Code Playgroud)
}
该代码按原样运行。问题是,当我按“注册”时,子组件中的任何内容都不会得到验证。(在本例中是宠物名称和性别)
演示图片:表格
我有的问题:
我需要使用模板驱动或反应式表单吗?我之前说过模板驱动的表单更容易,并且对于我的情况来说不需要,但是我对此不太确定。
我需要将表单传递给子表单还是将子表单传递给主表单?有没有办法使用模板驱动表单来实现对子组件的验证?
请有人告诉我什么是正确的做法,给我一些反馈和任何建议。如果您想了解更多详细信息,请随时向我询问。
感谢您的时间。
之前的响应 - 在我看来 - 这是一个黑客响应,它给你的打字稿代码带来额外的负担并绕过框架机制。当您使用模板驱动表单时,它特别矫枉过正 - 不需要打字稿代码来控制表单。
解决方案?使用框架提供的内容(在您的子组件 @Component({}) 内):
viewProviders: [{provide: ControlContainer, useExisting: NgForm}]
Run Code Online (Sandbox Code Playgroud)
有关此操作的工作示例,请参阅此存储库
| 归档时间: |
|
| 查看次数: |
2663 次 |
| 最近记录: |