简体   繁体   English

以angular2模型驱动的形式重用组件

[英]Reuse components in angular2 model driven forms

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 我对angular2很新,过去几天我一直在尝试使用模型驱动的表单创建可重用的表单组件

So lets say we have a component componentA.component.ts 所以我们假设我们有一个组件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 和组件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 例如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. 也就是说,我不希望我的Main组件知道formControlNames [ valueA1valueA2valueB ]的名称,而是自动插入它们并在顶级表单组上更新/验证。

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: 这可以通过将我们的顶级FormGroup传递给子组件并让子组件使用formGroupName将其自身添加到更高级别的FormGroupformGroupName ,这种方式上层FormGroup基本上不需要知道更低级别:

main.component.ts 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. 我们还将删除formA,formB声明,因为它们不再使用。

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-a.component.ts [formGroup]是我们的父组, formGroupName是我们如何识别和附加组件的控件作为一个组来工作在更大的整体(它们将嵌套在父组内)。

@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 这里有一个plunker (注意我在这里使组件B更加动态,看看是否可以完成,但上面的实现同样适用于B)http//plnkr.co/edit/fYP10D45pCqiCDPnZm0u?p =预习

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM