如何允许嵌套组件被其父级跟踪并在 Angular 中从其父级获取值? [英] How to allow nested components to be tracked by their parent and get values from their parent in Angular?

查看:25
本文介绍了如何允许嵌套组件被其父级跟踪并在 Angular 中从其父级获取值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列表单(每个表单由 1 个组件管理).

这些表单中有一种输入模式(例如,其中许多需要允许输入地址),我必须重构为可重用组件,因为它们在多种表单中使用,我不想重复无论是他们的逻辑还是他们的模板.

每个可重用的组件都必须

  1. 有它的逻辑
  2. 有包含输入标签的模板,没有
    标签
  3. 有其客户端验证约束
  4. 可能从其父级接收初始值
  5. 能够将其字段的值作为对象返回给父级(例如 address: {street: "...", "city": "...", ...})
  6. 如果不满足验证约束,则使父表单无效
  7. 一旦用户更改了父表单的值,就使其触摸"

来自本教程 对于 Angular2,我了解如何实现目标 124.

本教程中的解决方案也允许实现其他目标,但它通过从父级执行所有操作来实现(参见 app.component.ts#initAddress).

我怎样才能实现 3567,同时声明控件和他们对孩子的约束?

解决方案

如果您想在子组件中提供所有内容,您可以尝试这样的操作.

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

  1. have its logic
  2. have its template containing input tags and no <form> tag
  3. have its client validation constraints
  4. possibly receive initial values from its parent
  5. be able to return the value of its fields to the parent as an object (e.g. address: {street: "...", "city": "...", ...})
  6. make the parent form invalid if its validation constraints are not satisfied
  7. 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 中从其父级获取值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆