【问题标题】:Pass form to child component and validate the form in child component将表单传递给子组件并在子组件中验证表单
【发布时间】:2020-01-25 03:02:27
【问题描述】:

我在父组件中有一个提交按钮。我也有几个子组件。现在,我想启用按钮以在验证通过后将表单的所有值保存在所有子组件中。 在父组件中,我创建了表单组。

 public mainForm: FormGroup;

在父组件的构造函数中,

      constructor(private fb: FormBuilder) {
       this.mainForm = this.fb.group({
       child1Form: this.fb.group({
           projectName: [null, Validators.required],
           projectSource: [null, Validators.required]
       });
      });
     }

在父 html 中,我们将表单传递给子。

<div>
  <app-child1 [child1Form]="mainForm.controls['child1Form']"></app-child1>
</div> 

在子组件html中,代码为:

<form [formGroup]="child1Form">
   <div>
      <input [(ngModel)]="projectName" formControlName="projectName">
   </div>
   <div>
      <input [(ngModel)]="projectSource" formControlName="projectSource">
   </div>
</form>

在子组件的ts文件中,我们使用父组件的表单。

 @Input() child1Form: any;

我要的是父组件的ngOnInit,检查表单验证。

ngOnInit() {
   this.mainForm.statusChanges.subscribe(data => {
      const f = this.mainForm.controls['child1Form'];
      if(f.valid || f.dirth)
        // do something such as enable/disable the submit button
   });
}

但是我的问题是代码没有达到statusChanges 部分,即使我更改了子组件输入控件中的文本。我假设当我输入某些内容时,表单的值或状态会发生变化,因此我可以进行验证。

【问题讨论】:

  • 在您的子组件上尝试&lt;input formControlName="projectName"&gt;&lt;input formControlName="projectSource"&gt;
  • @HuiZhao,你不需要订阅状态更改来启用按钮,只需在 .html `
  • @Eliseo,我有几个子表单,child1 只是演示的一个例子。
  • 我的错,我忘了在演示中添加formControlName,刚刚更新了它。我在我的真实代码中有它。
  • [enabled]="this.mainForm.valid"&gt;submit&lt;/button&gt; 整个表格

标签: angular


【解决方案1】:

让我们一步一步解决这个问题:

  1. 创建一个parent & child 组件
  2. parent.component.html 中添加以下 HTML 模板
<form>
  <app-child></app-child>
  <button>Submit</button>
</form>
  1. child.component.html 中添加以下 HTML 模板
<form [formGroup]="child1Form">
  <div>
    <input type="text" formControlName="projectName" required>
  </div>
  <div>
    <input type="text" formControlName="projectSource" required>
  </div>
</form>
  1. child.component.ts 中为 child1Form 创建一个 formGroup(我在 'child.component.ts' 而不是在 'parent. component.ts')
  child1Form: FormGroup;

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.child1Form = this.fb.group({
      projectName: ['', Validators.required],
      projectSource: ['', Validators.required]
    })
  }
  1. 现在,订阅 statusChanges 并发出 child.component.ts 中的值
  @Output() isChild1FormValid: EventEmitter<boolean> = new EventEmitter<boolean>();

  ngOnInit() {
    this.child1Form.statusChanges.subscribe(value => {
      if(value === 'VALID') {
        this.isChild1FormValid.emit(true);
      }
    });
  }
  1. 监听 parent.component.html 中发出的值
<form>
  <app-child (isChild1FormValid)="enableSubmitButton($event)"></app-child>
</form>
  1. 将值保存在 parent.component.ts 内的属性中
  isChild1FormValid: boolean;

  enableSubmitButton(isValid: boolean) {
    this.isChild1FormValid = isValid;
  }
  1. 如果isChild1FormValid 属性为true (parent.component.html),则启用提交按钮
<form>
  <button type="submit" [disabled]="!isChild1FormValid">Submit</button>
</form>
  1. Full working demo in StackBlitz

【讨论】:

  • Sakib,isChild1FormValid 是不必要的“输出”。一个 formGroup 是有效的,它的所有 formGroup 和 formControls 都是有效的。您可以签入 main.component。真的不需要订阅 statusChanged,每次更改输入时,Angular 都会知道表单是否有效
  • 如果我有多个子组件,我应该使用[disabled]="!isChild1FormValid ||!isChild2FormValid || !isChild3FormValid || .... "这样的长条件吗
  • 使用&amp;&amp;而不是| |
  • 我在你的父组件中看到有一个form 标签(第6步)。但是你在 StackBlitz 中没有它。
  • 奇怪!我看到了一个form 标签。这里是父组件代码&lt;form&gt; &lt;app-child (isChild1FormValid)="enableSubmitButton($event)"&gt;&lt;/app-child&gt; &lt;button type="submit" [disabled]="!isChild1FormValid"&gt;Submit&lt;/button&gt; &lt;/form&gt;
猜你喜欢
  • 2021-11-08
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 2017-12-31
相关资源
最近更新 更多