在此处使用Angular 6:
我有一个父组件,其中有3个子组件。 子级1组件具有文本字段,子级2组件具有下拉列表,子级3组件具有下拉列表和提交按钮。
在子项3的提交单击按钮上,我要验证所有需要输入的子项child1,child2和child3的输入,并相应地引发错误。
使用angularjs,我可以绑定到ngmodel并检查表单是否无效。我该怎么做呢?我的意思是我怎样才能将输入状态从一个孩子传递给另一个孩子等等。 在搜索时,我发现了反应形式的概念,但是大多数文章都是仅输入内容的父母形式。
如果有人可以提供帮助,将不胜感激。下面是我的代码
-更新-
发布此帖子后,我更新了以下代码:https://medium.com/@joshblf/using-child-components-in-angular-forms-d44e60036664
但是这个继续在控制台中给我错误:“ 错误:formControlName必须与父formGroup指令一起使用。您需要添加一个formGroup 指令并将其传递给现有FormGroup实例(您可以在类中创建一个)。“
-具有响应形式的更新代码-
--Parent--
<form class="form-horizontal" [formGroup]="myForm">
<div class="row">
<ct-child1 [myForm]="myForm"></ct-child1>
<ct-child2> </ct-child2>
</div>
<div class="row">
<ct-child3></ct-child3>
</div>
</form>
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'ct-parent',
templateUrl: './parent.component.html']
})
export class ParentComponent implements OnInit {
myForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.myForm = this.fb.group({
uname: ['', Validators.required]
});
}
}
--Child 1--
<div class="panel-body">
<div class="form-group">
<label for="myForm" class="col-sm-3 control-label">Name:</label>
<div class="col-sm-8">
<input type="text" class="form-control" name="uname" [formControlName]="'uname'" placeholder="Enter Name..." required >
</div>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'ct-child1',
templateUrl: './child1.component.html']
})
export class Child1Component implements OnInit {
@Input() myForm: FormGroup;
constructor() { }
uname: string;
ngOnInit() { }
}
答案 0 :(得分:0)
我将子3组件中的提交按钮移到父组件中,然后您可以使用@ViewChild()
获取对子组件和组件中表格的引用,这将使您可以检查它们的有效性
import { Component, OnInit, ViewChild } from '@angular/core';
@Component({
selector: 'ct-parent',
templateUrl: './parent.component.html']
})
export class ParentComponent implements OnInit {
@ViewChild(Child1Component) child1Component: Child1Component;
@ViewChild(Child2Component) child2Component: Child2Component;
@ViewChild(Child3Component) child3Component: Child3Component;
constructor() {}
ngOnInit() {}
submitlClicked() {
//check if form is valid, else throw error
if (this.child1Component.myFormGroup.valid
&& this.child2Component.myFormGroup.valid
&& this.child3Component.myFormGroup.valid) {
// do something
} else {
// throw error
}
}
}
您需要更改代码并使用Reactive Forms
(https://angular.io/guide/reactive-forms):
-- Child 1 --
<form [formGroup]="myFormGroup">
<div class="panel-body">
<div class="form-group">
<label class="col-sm-3 control-label">Name:</label>
<div class="col-sm-8">
<input type="text" class="form-control" name="uname" formControlName="name" placeholder="Enter Name..." required>
</div>
</div>
</div>
</form>
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'ct-child1',
templateUrl: './child1.component.html']
})
export class Child1Component implements OnInit {
myFormGroup: FormGroup;
constructor(private fb: FormBuilder) {
myFormGroup = this.fb.group({
name: ['', Validators.required]
});
}
ngOnInit() {}
}
答案 1 :(得分:0)
在父级中构建表单,将所需的任何字段或嵌套的表单组传递给子级。父母会意识到孩子身上发生的一切。它知道特定的表单控件是否有效,整个表单是否有效...它需要了解的有关表单的所有信息!
在您的父母中建立表单,传递您想要的任何字段。如果没有传递给子级的嵌套表单组,则需要将整个父表单传递给子级(ren),因为子组件中显示的所有字段都必须包装在一个表单组中。在您的示例中,我们要担心的是,您希望像您一样将整个表单作为@Input
传递给孩子。然后在您的孩子中,包装表单组中的字段,就像“常规”表单一样:
<div [formGroup]="myForm">
<label>Name:</label>
<input type="text" formControlName="uname" placeholder="Enter Name...">
</div>
也请从formControlName
中删除括号,因为您没有尝试使用变量绑定,所以您的formcontrol简称为uname
。另外,您也不需要在模板中标记required
,因为在您设置Validators.required
(或您想要的任何 validator )。
显示可用于调用hasError()
的验证错误,因此在此示例myForm.hasError('required', 'uname')
中可以设置*ngIf
。
正如我提到的,在父级中具有“提交”按钮,因为父级控制着整个表单。我猜您可以在子级3中使用该按钮,但我认为将其复杂化并没有必要,需要轻松地将其放入父级表单中,以便轻松地将其放入父级表单中。家长,这也是建议的做法:
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<ct-child1 [myForm]="myForm"></ct-child1>
<button type="submit">Submit</button>
</form>
Here's a sample for you 。只是有一个孩子,但是您可以拥有任意多个孩子,就像我们对孩子1一样,遵循相同的模式:)