2016-09-16 61 views
1

我想构建一个动态表单组件,它可以接受一个对象并生成一个新表单。我采用了棱角分明RC6Angular 2 JS(RC4和更新版本)中的嵌套表单

实例数据:

[{ 
formgrouplabel: "registration", 
data:[{ 
    type: "checkbox", 
    label: "checkbox 1", 
    name: "checkbox1", 
    default: false, 
    required: false}, 
    { 
    type: "radio", 
    label: "mr", 
    name: "sex", 
    default: true, 
    required: true}, 
    { 
    type: "radio", 
    label: "miss", 
    name: "sex", 
    default: false, 
    required: true}]}, 
{ 
formgrouplabel: "some other part of the form", 
data: [another array with input objects] 
}] 

实际的对象将包括更像验证及其他要求的信息。我也想将输入分组。

我建立相应的角度成分:

<dynamic-form></dynamic-form> 
<dynamic-form-group></dynamic-form-group> 
<dynamic-checkbox></dynamic-checkbox> 
<dynamic-radiobutton></dynamic-radiobutton> 

以我动态型基团的模板I * ngFor过在数据对象中的所有formgroups。然后使用ngSwitchCase将复选框对象传递给动态复选框组件,并将单选按钮对象传递给动态单选按钮组件。

所有这些现在工作得很好,生成整体的形式,然而:

当我现在使用ngModel该动态复选框组元内例如以配合一个FormControl到输入元件,ngModel是不能够与动态表单组件上的ngForm进行通信(两层以上)。 动态窗体组组件中的FormGroup也无法与ngForm进行通信。总之,没有什么是可以让孩子沟通的。

我正在阅读ng-book 2和角度文档上的所有示例,但我找不到干净的解决方案。我知道如果你想要一个子元素与它的父母通信,你可以通过@Export和事件发射器创建一个服务或者导出一个特定的值/对象或者函数。然而,这并没有导致一个干净的解决方案。

现在我明白的问题是,当你使用FormBuilder或FormGroup和FormControl,你必须先实例化控件: this.form = new FormGroup({checkboxControl:new FormControl(“some value”)});

或(如写在书NG 2)

myForm: FormGroup; 
constructor(fb: FormBuilder) { this.myForm = fb.group({ 
     'sku': ['ABC123'] 
    }); 
} 

这两个是不是真的我的选择。由于对象模型,我的表单将首先创建,接下来是我的表单组,最后是我的表单控件。为了使用上述方法,应该是相反的方法。

有没有办法先创建表单组并稍后添加controlls? 我想这已经:

this.form = new FormGroup({}); 
this.form.controls['newControl'] = new FormControl({"some value"}); 

这并不一个新formControl添加到现有FormGroup,然而,当该输入的值更改不同,FormControl不更新。这就像我只引用了“新的FormControl({”some value“});”价值总是停留在“某种价值”上。

最后我也试过这种方法: ​​

这里也是他们先建formcontrols,然后将它们传递作为一个对象来创建一个formgroup。

当然,我可以将所有模板和控制逻辑放入动态表单组件,并省略动态表单组,动态复选框和其他组件,但是有什么方法可以使我的工作成为我打算? 我希望有人已经用新的表单api构建了一些复杂的东西。

回答

1

查看FormGroup上的addControl()功能。对于各种场景,FormGroup,FormArray,FormControl等都有相当多的方便的内置方法。

使用示例

/* 
    basic-form-question.component.ts -> From Angular Dynamic Form Documentation 
*/ 
@Component({ 
    selector: 'df-question', 
    templateUrl: './basic-form-question.component.html' 
}) 
export class DynamicFormQuestionComponent implements OnInit { 
    @Input() question: QuestionBase<any>; 
    @Input() form: FormGroup; 

    ngOnInit() { 
     if(!this.form.controls.hasOwnProperty(this.question.key)){ 
      let control = new FormControl(this.question.value || '', Validators.required); 

      this.form.addControl(this.question.key, control); 
     } 
    } 
} 

希望这有助于。

+0

这似乎工作,有一个我不太喜欢的小调整,但比以前更好。我将formgroup作为一个对象传递给子对象(例如DynamicFormQuestionComponent)。这是它自己的是不够的,因为除非在模板中特别提到了formGroup,否则formControlName不能绑定到formGroup。我将formGroup传递给子元素“parentformgroup”。在子组件模板内部,我添加以下[formGroup] =“parentformgroup”。这实现了我想要的。感谢您的精彩投入! – Zap

+0

不幸的是,这似乎是目前在Angular 2中以动态形式做事的标准方式,但这只是一个小小的警告。尽管我这样做的方式是在模板中使用FormControl而不是FormControlName,因为你可以避免在模板中声明关系。 –