1

我正在研究 Angular 10。我在 Angular 模板驱动和反应式表单方面遇到问题已经 3 天了。

我想做的事:创建一个包含许多子组件的复杂表单(以便分离大量代码)。然后单击一个按钮,我想验证所有表单和子组件。我想以某种方式验证子组件。

我创建的内容:具有 2 向绑定的模板驱动表单,因为我相信它更容易并且不需要我的情况。

我设法使验证仅适用于基本表单。我无法在子组件上做到这一点。我看到很多关于这个问题的帖子并尝试了很多,但我很困惑。

我的代码:

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>

子组件.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>

childrencomponent.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 {
  }

}

父.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));
  }

}

代码按原样工作。问题是当我按下注册时,子组件中的任何内容都不会得到验证。(在这种情况下是宠物名称和性别)

演示图片:表格

我的问题:

  1. 我需要使用模板驱动或反应式表单吗?我之前说过,模板驱动的表单更容易,我的情况不需要,但是我不太确定这一点。

  2. 我需要将表格传递给孩子还是将孩子传递给主表格?有没有办法使用模板驱动表单对子组件进行验证?

请有人能告诉我什么是正确的做法,给我一些反馈和任何建议。不要犹豫,问我任何事情,或者如果你想了解更多细节。

感谢您的时间。

4

2 回答 2

0

我已经设法实现了一些有效的东西。

我所做的是 @ViewChild(ChildComponent) child-Component: ChildComponent;在parent.ts中添加。

然后在子组件中,我创建了一个检查子表单的函数,如果有任何错误,我返回一个布尔变量。该函数在父级中使用。我正在为每个孩子做这件事。不久,我在每个子组件中进行表单验证,并且在父组件中得到一个布尔变量。

在父母中,我有类似的东西:

if (!this.child-Component.validform) {
        console.log("child has missing inputs");
      }
于 2020-09-29T14:30:59.500 回答
0

你可以传入一个formControl

 @Input() formControl: FormControl;

然后像这样通过

  <app-extra-info  [formControl]="f.get('petName')"></app-extra-info> pass model in children

然后将表单传递给提交

<form name="form" (ngSubmit)="onSubmit(f.form)" #f="ngForm" novalidate>


onSubmit(form: FormGroup) {
    form.get('petName').updateValueAndValidity();

    alert( form.get('petName').valid);
  }
于 2020-09-16T10:36:57.163 回答