以 angular2 模型驱动形式重用组件 [英] Reuse components in angular2 model driven forms

查看:32
本文介绍了以 angular2 模型驱动形式重用组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 angular2 还很陌生,在过去的几天里,我一直在尝试使用模型驱动的表单创建可重用的表单组件

假设我们有一个组件 componentA.component.ts

@Component({选择器:'common-a',模板:`<div [formGroup]="_metadataIdentifier"><div class="form-group"><label>Common A[1]</label><div><input type="text" formControlName="valueA1"><小>说明1</小>

<div class="form-group"><label>Common A[2]</label><div><input type="text" formControlName="valueA2"><small>描述 2</small>

`})导出类 ComponentA 实现 OnInit{@Input('组')公共 myForm:FormGroup;构造函数(私有_fb:FormBuilder){}ngOnInit() {this.myForm = this._fb.group({valueA1 : ['', [Validators.required]],valueA2 : ['', [Validators.required]],});}}

还有一个组件 B componentB.component.ts

@Component({选择器:'common-b',模板:`<div [formGroup]="_metadataIdentifier"><div class="form-group"><label>Common B</label><div><input type="text" formControlName="valueB"><small>描述</small>

`})导出类 ComponentB 实现 OnInit{@Input('组')公共 myForm:FormGroup;构造函数(私有_fb:FormBuilder){}ngOnInit() {this.myForm= this._fb.group({valueB : ['', [Validators.required]]});}}

我的问题是如何使用这两个子组件组成一个表单,而无需将输入的控制转移到主组件.例如一个 main.component.ts

@Component({选择器:'主要',模板:`<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm.value)"><div><common-a [group]="formA"></common-a><common-b [group]="formB"></common-b><div><button>注册!</button>

</表单>`})导出类 Main 实现 OnInit{@Input('组')公共 myForm:FormGroup;公共表单A:表单组;公共表单B:表单组;构造函数(私有_fb:FormBuilder){}ngOnInit() {this.myForm = this._fb.group({//我如何在这里组合这两个子表单//让表单控件名称对这个组件不可知});}}

这个想法背后的概念是构建许多共享一些构建块的复杂表单.

也就是说,我不希望我的 Main 组件知道 formControlNames [valueA1,valueA2,valueB] 但会自动插入它们并在顶级表单组上更新/验证.

任何指向正确方向的想法或点都会有所帮助.

解决方案

这可以通过将我们的顶级 FormGroup 传递给子组件并让子组件将自身添加到更高级别来实现FormGroup 使用 formGroupName 这样上层 FormGroup 基本上不需要知道下层:

ma​​in.component.ts

模板:`<...><common-a [parentForm]="myForm"></common-a><...>

我们还将删除 formA、formB 声明,因为它们不再使用.

component-a.component.ts [formGroup] 是我们的父组,formGroupName 是我们将如何识别和附加组件的控件作为一个小组在更大的整体中工作(它们将嵌套在父组中).

@Component({<...>模板:`<div [formGroup]="parentForm"><div class="form-group"><label>Common A[1]</label><div formGroupName="componentAForm"><input type="text" formControlName="valueA1"><小>说明1</小>

<div class="form-group"><label>Common A[2]</label><div formGroupName="componentAForm"><input type="text" formControlName="valueA2"><small>描述 2</small>

`})导出类 ComponentA 实现 OnInit {@Input() parentForm: FormGroup;componentAForm:FormGroup;构造函数(私有_fb:FormBuilder){}ngOnInit() {this.componentAForm = this._fb.group({valueA1: ['', Validators.required],valueA2: ['', Validators.required]});this.parentForm.addControl("componentAForm", this.componentAForm);}}

这里有一个 plunker (注意,我在这里让组件 B 更加动态,只是为了看看它是否可以完成,但上面的实现同样适用于 B):http://plnkr.co/edit/fYP10D45pCqiCDPnZm0u?p=preview

I'm fairly new to angular2 and for the past few days I have been trying to create reusable form components using model driven forms

So lets say we have a component componentA.component.ts

@Component({
    selector: 'common-a',
    template: `
    <div [formGroup]="_metadataIdentifier">
        <div class="form-group">
        <label>Common A[1]</label>
        <div>
            <input type="text" formControlName="valueA1">
            <small>Description 1</small>
        </div>
        <div class="form-group">
        <label>Common A[2]</label>
        <div>
            <input type="text" formControlName="valueA2">
            <small>Description 2</small>
        </div>
    </div>
    `
})


export class ComponentA implements OnInit{

    @Input('group')
    public myForm: FormGroup;

    constructor(private _fb: FormBuilder) {
    }

    ngOnInit() {
        this.myForm = this._fb.group({
            valueA1 : ['', [Validators.required]],
            valueA2 : ['', [Validators.required]],
        });
    }
}

And a component B componentB.component.ts

@Component({
    selector: 'common-b',
    template: `
    <div [formGroup]="_metadataIdentifier">
        <div class="form-group">
        <label>Common B</label>
        <div>
            <input type="text" formControlName="valueB">
            <small>Description</small>
        </div>
    </div>
    `
})


export class ComponentB implements OnInit{

    @Input('group')
    public myForm: FormGroup;

    constructor(private _fb: FormBuilder) {
    }

    ngOnInit() {
        this.myForm= this._fb.group({
            valueB : ['', [Validators.required]]
        });
    }
}

My question is how can I compose a form using this two sub components without moving the control of the inputs to the main component. For example a main.component.ts

@Component({
    selector: 'main',
    template: `
    <form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm.value)">
        <div>
            <common-a [group]="formA"></common-a>
            <common-b [group]="formB"></common-b>
            <div>
                <button>Register!</button>
            </div>
        </div>
    </form>
    `
})


export class Main implements OnInit{

    @Input('group')
    public myForm: FormGroup;

    public formA : FormGroup;

    public formB : FormGroup;

    constructor(private _fb: FormBuilder) {
    }

    ngOnInit() {
        this.myForm = this._fb.group({
            //how can I compose these two sub forms here
            //leaving the form control names agnostic to this component
        });
    }
}

The concept behind this idea is to build many complex forms that share some of their building blocks.

That is, I don't want my Main component to know the names of the formControlNames [valueA1,valueA2,valueB] but automagically insert them and update/validate on the top level form group.

Any ideas or points to the right direction would be helpfull.

解决方案

This can be accomplish by passing in our top level FormGroup to the child component and having the child component add itself into the higher level FormGroup using formGroupName that way the upper level FormGroup needs to know essentially nothing about the lower levels:

main.component.ts

template: `<...>
    <common-a [parentForm]="myForm"></common-a>
    <...>

We will also get rid of the formA, formB declarations as they are no longer used.

component-a.component.ts [formGroup] is our parent group, formGroupName is how we will identify and attach the component's controls as a group to work in the larger whole (they will nest inside the parent group).

@Component({<...>
template: `
<div [formGroup]="parentForm">
    <div class="form-group">
    <label>Common A[1]</label>
    <div formGroupName="componentAForm">
        <input type="text" formControlName="valueA1">
        <small>Description 1</small>
    </div>
    <div class="form-group">
    <label>Common A[2]</label>
    <div formGroupName="componentAForm">
        <input type="text" formControlName="valueA2">
        <small>Description 2</small>
    </div>
</div>`
})

export class ComponentA implements OnInit {
     @Input() parentForm: FormGroup;
     componentAForm: FormGroup;

     constructor(private _fb: FormBuilder) {}

     ngOnInit() {
         this.componentAForm = this._fb.group({
             valueA1: ['', Validators.required],
             valueA2: ['', Validators.required]
         });

         this.parentForm.addControl("componentAForm", this.componentAForm);
     }
}

Here's a plunker (note that I made component B a little more dynamic here just to see if it could be done, but the implementation above for is equally applicable to B): http://plnkr.co/edit/fYP10D45pCqiCDPnZm0u?p=preview

这篇关于以 angular2 模型驱动形式重用组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆