在angular2模型驱动的表单中重用组件

在angular2模型驱动的表单中重用组件

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

问题描述

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

然后让我们说我们有一个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>描述1< / small>
< / div>
< div class =form-group>
< label> Common A [2]< / label>
< div>
< input type =textformControlName =valueA2>
< small>描述2< / small>
< / div>
< / div>
`
})


导出类ComponentA实现OnInit {

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

构造函数(private _fb:FormBuilder){
}

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

并且组件B componentB .component.ts


$ b

  @Component({
选择器:'common-b',
模板:`
< div [formGroup] =_ metadataIdentifier>
< div class =form-group>
< label>常用B< / label>
< div>
< / type> text" form"> $ b< b< small>描述< / small> ;
< / div>
< / div>
`
})


导出类ComponentB实现OnInit {

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

构造函数(private _fb:FormBuilder){
}

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


$ / code $ / pre

我的问题是我怎样才能用这个两个子组件,而不将输入的控制移动到主组件。
例如a main.component.ts

  @Component({
selector:'main',
template:`
< form [formGroup] =myForm(ngSubmit)=onSubmit(myForm。值)>
< div>
< common-a [group] =formA>< / common-a>
< common-b [group] =formB>< / common-b>
< div>
<按钮>注册!< /按钮>
< / div>
< ; / div>
< / form>
`
})


导出类主要实现OnInit {

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

public formA:FormGroup;

public formB:FormGroup;

构造函数(private _fb:FormBuilder){
}

ngOnInit(){
this.myForm = this._fb.group({
//我如何在这里编写这两个子表单
//将表单控件名称不可知到这个组件
});


$ / code>

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



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



任何想法或指向右侧方向将是有帮助的。

解决方案

这可以通过传递顶层 FormGroup 添加到子组件,并让子组件使用 formGroupName 将它自己添加到更高层级 FormGroup 中上层 FormGroup 需要对下层的信息几乎一无所知:

main.component.ts

 模板:`< ...> 
< ...>

我们也将摆脱formA,formB声明,因为它们不再被使用。



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

  @Component({< ...> 
模板:`
< div [formGroup] =parentForm>
< div class =form-group>
< label> Common A [1]< / label>
< div formGroupName =componentAForm>
$ lt; / div>
< div class =form- group>
< label> Common A [2]< / label>
< div formGroupName =componentAForm>
< input type =textformControlName = valueA2>
< small>说明2< / small>
< / div>
< / div>`
})

导出类ComponentA实现OnInit {
@Input()parentForm:FormGroup;
componentAForm:FormGroup;

构造函数(private _fb:FormBuilder){}

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

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


$ / code $ / pre
$ b $ p

这里是一个plunker 组件B在这里稍微动态一点,以查看它是否可以完成,但上面的实现同样适用于B)


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模型驱动的表单中重用组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 02:45