如何允许嵌套组件由其父级跟踪并从Angular中的父级获取值? [英] How to allow nested components to be tracked by their parent and get values from their parent in Angular?
问题描述
我有一系列表格(每个表格由一个组件管理).
I have a series of forms (each managed by 1 component).
在这些形式中有一种输入模式(例如,许多形式要求输入地址),我不得不将其重构为可重用的组件,因为它们以多种形式使用并且我不想重复既不是他们的逻辑也不是他们的模板.
There is a pattern of inputs in these forms (e.g. many of them require to allow input of an address) that I have to refactor into re-usable components as they are used in multiple forms and I don't want to duplicate neither their logic nor their templates.
每个可重用组件都必须
- 有其逻辑
- 其模板包含输入标签,没有
<form>
标签 - 具有其客户端验证约束
- 可能会从其父级接收初始值
- 能够将其字段的值作为对象返回给父对象(例如
address: {street: "...", "city": "...", ...}
) - 如果不满足其验证约束条件,则使父表单无效
- 一旦用户更改了父表单的值,就使其被触摸"
- have its logic
- have its template containing input tags and no
<form>
tag - have its client validation constraints
- possibly receive initial values from its parent
- be able to return the value of its fields to the parent as an object (e.g.
address: {street: "...", "city": "...", ...}
) - make the parent form invalid if its validation constraints are not satisfied
- make the parent form "touched" once its values have been changed by the user
来自本教程对于Angular2,我了解如何实现目标 1 , 2 和 4 .
本教程中的解决方案还可以实现其他目标,但是可以通过从父级执行所有操作(请参见app.component.ts#initAddress
)来实现.
The solution in the tutorial allows to achieve also the other objectives, but it does so by doing everything from the parent (see app.component.ts#initAddress
).
我如何实现 3 , 5 , 6 和 7 ,同时声明控件和他们对孩子的约束?
How can I achieve 3, 5, 6 and 7, while declaring controls and their constraints within the child?
推荐答案
如果要在子组件中提供所有内容,则可以尝试类似的操作.
If you want to provide everything in the child component you can try something like this.
import { Component, Input } from '@angular/core';
import { FormGroupDirective, ControlContainer, Validators, FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'address',
template: `
<div formGroupName="address">
<input formControlName="city" placeholder="city" (blur)="onTouched" />
<input formControlName="country" placeholder="country" (blur)="onTouched" />
<input formControlName="zipCode" placeholder="zipCode" (blur)="onTouched" />
</div>
`,
styles: [`h1 { font-family: Lato; }`],
viewProviders: [
{ provide: ControlContainer, useExisting: FormGroupDirective }
]
})
export class AddressComponent {
private form: FormGroup;
constructor(private parent: FormGroupDirective) { }
ngOnInit() {
this.form = this.parent.form;
const city = new FormControl('', Validators.required);
const country = new FormControl('', Validators.required);
const zipCode = new FormControl('', Validators.required);
const address = new FormGroup({ city, country, zipCode });
this.form.addControl('address', address);
}
}
用法:
import { Component } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'my-app',
template: `
<form [formGroup]="form">
<address></address>
</form>
{{ form.value | json }}
`,
styleUrls: ['./app.component.css'],
})
export class AppComponent {
form: FormGroup;
constructor() {
this.form = new FormGroup({});
}
}
请注意,我正在使用ReactiveFormsModule
.
Please note that I'm using the ReactiveFormsModule
.
还要确保检查角形-Kara Erickson .该演示向您展示了如何使用模板驱动形式和反应形式的实现来创建可重用的地址组件.
Also make sure to check out Angular Forms - Kara Erickson. The presentation shows you how to create a reusable address component with implementations for both, template driven and reactive forms.
这篇关于如何允许嵌套组件由其父级跟踪并从Angular中的父级获取值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!