本文介绍了如何允许嵌套组件被其父级跟踪并在 Angular 中从其父级获取值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一系列表单(每个表单由 1 个组件管理).
这些表单中有一种输入模式(例如,其中许多需要允许输入地址),我必须重构为可重用组件,因为它们在多种表单中使用,我不想重复无论是他们的逻辑还是他们的模板.
每个可重用的组件都必须
- 有它的逻辑
- 有包含输入标签的模板,没有
标签 - 有其客户端验证约束
- 可能从其父级接收初始值
- 能够将其字段的值作为对象返回给父级(例如
address: {street: "...", "city": "...", ...}代码>)
- 如果不满足验证约束,则使父表单无效
- 一旦用户更改了父表单的值,就使其触摸"
来自本教程 对于 Angular2,我了解如何实现目标 1、2 和 4.
本教程中的解决方案也允许实现其他目标,但它通过从父级执行所有操作来实现(参见 app.component.ts#initAddress
).
我怎样才能实现 3、5、6 和 7,同时声明控件和他们对孩子的约束?
解决方案
如果您想在子组件中提供所有内容,您可以尝试这样的操作.
import { Component, Input } from '@angular/core';导入 { FormGroupDirective, ControlContainer, Validators, FormGroup, FormControl } from '@angular/forms';@成分({选择器:'地址',模板:`<div formGroupName="地址"><input formControlName="city" placeholder="city" (blur)="onTouched"/><input formControlName="country" placeholder="country" (blur)="onTouched"/><input formControlName="zipCode" placeholder="zipCode" (blur)="onTouched"/>
`,样式:[`h1 { 字体系列:拉托;}`],视图提供者:[{ 提供: ControlContainer, useExisting: FormGroupDirective }]})导出类 AddressComponent {私有表单:FormGroup;构造函数(私有父级: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('地址', 地址);}}
用法:
import { Component } from '@angular/core';从@angular/forms"导入{FormGroup};@成分({选择器:'我的应用',模板:`<form [formGroup]="form"><地址></地址></表单>{{ 表单值 |json }}`,styleUrls: ['./app.component.css'],})导出类 AppComponent {表格:表格组;构造函数(){this.form = new FormGroup({});}}
请注意,我使用的是 ReactiveFormsModule
.
现场演示
另请务必查看Angular Forms - Kara Erickson.该演示文稿向您展示了如何创建一个可重用的地址组件,其中包含模板驱动和响应式表单的实现.
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.
Each re-usable component would have to
- 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
From this tutorial for Angular2, I understand how to achieve objectives 1, 2 and 4.
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
).
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);
}
}
Usage:
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({});
}
}
Please note that I'm using the ReactiveFormsModule
.
Live demo
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 中从其父级获取值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!