我是Angular的新手,我的任务似乎找不到最佳的方法。我有一个具有3个子组件的父组件,看起来像下面的图片。
当用户单击父控制器中的“保存”按钮时,如果表单有效,则来自“子1”和“子3”的所有表单输入以及来自“子2”的项目列表必须为保存到数据库中。只需调用一次Web api,就可以发送一个对象(该对象将包含一些字符串和一系列项目)。
我已经阅读了父组件和子组件之间进行通信的多种方法,但是我不确定在这种情况下最好的方法是什么。 如果我使用ViewChild,则父级将了解其他组件,因此它们将紧密结合在一起。 如果我使用Input / Output,那么我必须找到一种方法来点击所有值,但是仅在表单有效的情况下(我还没有找到方法) 如果我使用服务,我不知道它对表单有效性和返回表单值有帮助吗?
对于这些情况,当父级与多个子组件和复杂对象通信时,是否有最佳方法?任何有关此主题的信息或帮助将不胜感激。
答案 0 :(得分:0)
表单具有value and status changed events,更确切地说是可观察的。您可以为将代表此功能的子组件创建组件输出。一项更改值,另一项更改状态。无论何时触发它们,您都会在输出上发出新事件。
这样,在父组件中,您将始终始终具有所有表单的状态和值,并且可以在用户单击“保存”按钮时使用。例如,如果并非所有表格都有效,您也可以禁用该按钮。
答案 1 :(得分:0)
您的任务并不简单。我想重点是它是大形式。可能会出现验证问题。从Reactive Form开始,按FormGroup制作嵌套表单,如果需要使用绑定机制将其拆分为子组件。相关文章Angular2: Building nested, reactive forms
答案 2 :(得分:0)
app.component.ts
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);
}
}
app.component.html
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>
child1.component.ts
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() {
}
}
child1.component.html
<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>
添加两个与child1.component.ts和child1.component.html相同的子组件
此外,我还添加了必填字段验证功能,并基于该保存按钮已禁用和启用。
答案 3 :(得分:0)
这不是最简单的任务。但是我强烈建议您使用反应形式。然后,您可以使用Angulars FormGroup
在父组件中创建一个FormBuilder
。
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
subform1: this.fb.group({
input1: null,
input2: 'thisisastring'
}),
subform2: this.fb.group({
input1: null,
input2: null
})
})
}
get subform1(): FormGroup {
return this.form.get('subform1') as FormGroup;
}
现在,您可以在模板中将子表单组作为输入传递。
<form [formGroup]="form" (ngSubmit)="functionToSave(form.value)">
<app-subform1 [form]="subform1"></app-subform1>
</form>
在您的子组件中,您现在可以创建上面的表单
@Input() form: FormGroup;
像这样在您的模板中使用它
<div [formGroup]="form">
<input formControlName="input1">
</div>
,不使用form
标签。然后,在父组件中创建functionToSave
函数来处理所有数据。为了进行验证,只需从@ angular / forms导入Validators
并像这样使用FormBuilder
this.form = this.fb.group({
subform1: this.fb.group({
input1: [null, Validators.required]
})
})