2016-09-16 57 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,因爲你可以避免在模板中聲明關係。 –