理解Angular的Reactive Form

原文連接git

官方文檔並無說明Template-driven FormReactive Form 哪個更好。因爲以前開發過一個Ionic2項目,使用的是Template-driven Form,光是校驗就有一坨代碼,維護與開發簡直慘不忍睹,因此我的更加推薦使用Reactive Formgithub

使用Reactive Form(同步),咱們會在代碼中建立整個表單 form control 樹。咱們能夠當即更新一個值或者深刻到表單中的任意節點,由於全部的 Form control 都始終是可用的。並且由於是同步,有利於單元測試。後端

Template-driven Form(異步)中,咱們是經過指令來建立 form control 的。咱們在操做一個Form control以前,必需要經歷一個變化檢測週期。數組

FormControl、FormGroup、FormArray

FormControl是最小單位(C),FormGroup相似於一個由FormControl(C)組件的object對象(G),FormArray(A)是一個由FormGroup(G)的Array數組。它們之間能夠互相嵌套,以應對各式各樣的表單模型(Form Model)。bash

addForm: FormGroup;

  constructor(public formBuilder: FormBuilder) {
    this.orderForm = this.formBuilder.group({
      name: ['', [Validators.required]],
      description: ['', [Validators.required]],
      other: this.formBuilder.group({
        name: ['', [Validators.required]],
        description: ['', [Validators.required]]
      }),
      items: this.formBuilder.array([
        this.formBuilder.group({
          name: ['', [Validators.required]],
          description: ['', [Validators.required]],
        }),
        this.formBuilder.group({
          name: ['', [Validators.required]],
          description: ['', [Validators.required]],
        }),
        this.formBuilder.group({
          name: ['', [Validators.required]],
          description: ['', [Validators.required]],
        })
      ])
    });
  }
  
複製代碼

經過this.addForm.value獲取的值:服務器

{
  name:'',
  description:'',
  other: {
    name:'',
    description:'',
  },
  items: [
    {
      name:'',
      description:'',
    },
    {
      name:'',
      description:'',
    },
    {
      name:'',
      description:'',
    }
  ]
}
複製代碼

它們三者之間的關係以下:antd

formGroup = 
{
  formControlName:formControl,
  formControlName:formControl,
  formControlName:formControl,
}

formArray = [
  formGroup,
  formGroup,
]= [
    {
      formControlName:formControl,
      formControlName:formControl,
      formControlName:formControl,
    },
    {
      formControlName:formControl,
      formControlName:formControl,
      formControlName:formControl,
    }
]
複製代碼

對於使用Reactive Form時,動態增長formControl也是很方便的。這種在,好比添加出差明細等狀況下很適合。 代碼示例參考數據結構

data model與form model

來自服務器就是數據模型(data model),而FormControl的結構就是表單模型(form model)。app

組件必須把數據模型中的英雄值複製到表單模型中。這裏隱含着兩個很是重要的點。異步

  • 開發人員必須理解數據模型是如何映射到表單模型中的屬性的。
  • 用戶修改時的數據流是從DOM元素流向表單模型的,而不是數據模型。表單控件永遠不會修改數據模型。

我的經驗:

  1. 按照如此的劃分,歷來能夠不依賴後端的數據結構(畢竟後端的數據格式是千奇百怪的)。
  2. 表單模型最好和要提交的數據格式同樣,數據的修改都是操做表單模型的 formControl。提交的時候不須要手動組裝數據。
  3. 因爲以前的項目使用的是Template-driven Form,須要手動組裝提交的數據,並且並無嚴格區分數據模型與表單模型,後期維護時,代碼很亂。
  4. 儘可能使用類型系統,不要圖方便使用any,否則維護的時候,這酸爽!!!

setValue 與 patchValue

  • setValue: 使用的時候須要每一個from control都要設置值。不然,ERROR Error: Must supply a value for form control with name: 'xxxxx'
  • patchValue: 相似打補丁,不須要每一個from control都要設置值。
相關文章
相關標籤/搜索