Angular 角度复杂组件通信

Angular 角度复杂组件通信,angular,Angular,我是个新手,我有一个任务,我似乎找不到最好的方法来完成它。我有一个父组件,它有3个子组件,看起来像下面的图片 当用户单击父控制器中的“保存”按钮时,如果表单有效,则必须将来自子1和子3的所有表单输入以及来自子2的项目列表保存到数据库中。对于WebAPI,只需进行一次调用,并发送一个对象(该对象将包含一些字符串和一个项目列表) 我已经了解到在父组件和子组件之间有多种通信方式,但我不确定在这种情况下什么是最好的。 如果我使用ViewChild,那么父级将了解其他组件,因此它们将紧密耦合。 如果我使用

我是个新手,我有一个任务,我似乎找不到最好的方法来完成它。我有一个父组件,它有3个子组件,看起来像下面的图片

当用户单击父控制器中的“保存”按钮时,如果表单有效,则必须将来自子1和子3的所有表单输入以及来自子2的项目列表保存到数据库中。对于WebAPI,只需进行一次调用,并发送一个对象(该对象将包含一些字符串和一个项目列表)

我已经了解到在父组件和子组件之间有多种通信方式,但我不确定在这种情况下什么是最好的。 如果我使用ViewChild,那么父级将了解其他组件,因此它们将紧密耦合。 如果我使用输入/输出,那么我必须找到一种方法在单击时发出所有值,但只有在表单有效的情况下才发出 如果我使用服务,我不知道它是否有助于表单有效性和返回表单值

在这些情况下,当父对象与多个子组件和复杂对象通信时,是否有最佳方法?非常感谢您提供有关此主题的任何信息或帮助

这些形状有一个更精确的可观察性。您可以为表示此项的子组件创建组件输出。一个表示值已更改,一个表示状态已更改。无论何时触发,都会在输出上发出新事件


这样,在父组件中,您将始终拥有所有窗体的状态和值,并且在用户单击“保存”按钮时可以使用。例如,如果不是所有表单都有效,您也可以禁用该按钮。

您的任务并不琐碎。我想主要的一点是它是一个大的形式。可能会出现验证问题。从开始,按FormGroup创建嵌套表单,并在需要时使用绑定机制将其拆分为子组件。有一篇相关文章

app.component.ts

app.component.html

child1.component.html


儿童1
添加与child1.component.ts和child1.component.html相同的两个子组件


此外,我还添加了require字段验证,并基于该保存按钮禁用和启用。

这不是最简单的任务。但我强烈建议使用反应形式。然后,您可以使用Angulars
FormBuilder
在父组件中创建一个
FormGroup

形式:FormGroup;
构造函数(私有fb:FormBuilder){
this.form=this.fb.group({
子表单1:this.fb.group({
input1:null,
输入2:“ThisisString”
}),
子表单2:this.fb.group({
input1:null,
input2:null
})
})
}
获取子表单1():FormGroup{
将此.form.get('subform1')作为FormGroup返回;
}
在模板中,您现在可以将子formgroups作为输入传入


子组件中,您现在可以创建如上所述的表单

@Input()表单:FormGroup;
然后像这样在模板中使用它


不使用
表单
标记。然后在父组件中,只需创建
函数来保存
函数来处理所有数据。对于验证,只需从@angular/forms导入
验证器
,然后像这样使用
FormBuilder

this.form=this.fb.group({
子表单1:this.fb.group({
input1:[空,验证器。必需]
})
})
不要
import { Component, ViewChild } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  title = "app";

  @ViewChild("child1Component") child1: any;
  @ViewChild("child2Component") child2: any;
  @ViewChild("child3Component") child3: any;

  save() {
    console.log(this.child1.form.value);
    console.log(this.child2.form.value);
    console.log(this.child3.form.value);
  }
}
 Parrent

    <button type="submit" (click)="save()" [disabled]="!child1.form.valid || !child2.form.valid || !child3.form.valid"> Save </button>

    <app-child1 #child1Component></app-child1>
    <app-child2 #child2Component></app-child2>
    <app-child3 #child3Component></app-child3>
import { Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-child1',
  templateUrl: './child1.component.html',
  styleUrls: ['./child1.component.css']
})
export class Child1Component implements OnInit {


  @ViewChild("child1Form") form: any;

  constructor() { }

  ngOnInit() {
  }

}
<div class="container">
  <h1>Child 1</h1>
  <form #child1Form="ngForm">
    <div class="form-group">
      <input type="text" class="form-control" name="input1" [(ngModel)]="input1" placeholder="Required" required>
    </div>

    <div class="form-group">
      <input type="text" class="form-control" name="input2" [(ngModel)]="input2">
    </div>


    <div class="form-group">
      <input type="text" class="form-control" name="input3" [(ngModel)]="input3">
    </div>


    <div class="form-group">
      <input type="text" class="form-control" name="input4" [(ngModel)]="input4">
    </div>

  </form>
</div>