來還債囉。
簡述
這個是在處理表單時我覺得比較麻煩的一個部分,再加上官方範例為了展現所有功能所以寫又更複雜了一些,總之我覺得沒有麼好懂,所以寫一篇筆記來記錄一下。
範例
簡單來說,假設我有一個表單,我希望他送出去時的資料是長這樣:
1 | const classRoom = { |
這時候第一個會碰到的問題是:我要怎麼產生 students
的欄位?畢竟我不可能這樣寫:
1 | <Form.Item label='Students' name='students'> |
這樣子在提交表單的時候只會被當成是新的欄位,像這樣:
附註:注意多了 name
跟 phone
這兩個欄位
如果還是不太清楚的話可以到這邊看實際範例。
總之呢,這邊要用 antd 提供的 Form.List
來做,先來看寫法:
1 | <Form form={form} initialValues={initRequest} onFinish={onFinish}> |
附註:
name
裡面的陣列順序一定要是[field.name, "phone"]
這樣的順序,否則會有問題。(重要!!!)- 不要把
onClick={() => operation.add()}
寫成onClick={operation.add}
。雖然這樣可以執行,但會有一些額外的問題。
當初我看到這裡也覺得很亂,不過只要一步一步來看就好。
首先 Form.List
的內容是一個 function,他的內容會長這樣:
1 | // function 中的參數 |
簡單來說就是用它提供給你的「這個 function」來產生內容,至於參數的部分我會一個一個解釋。
fields
這是用來代表列表中的每個欄位,不過它的值可能跟你想得不太一樣,把它印出來的結果是:
之所以會這樣子是因為當我們要渲染 students
時,我們會有多個相同的欄位,像是每個 student 都會有 name
和 phone
,這時候如果 fields
也用同樣的名稱的話會「撞名」,所以這邊才會自動產生從 0 遞增的數字來當作欄位名稱。
至於 key 雖然看起來也是從 0 開始遞增的數字,可是有一個很重要的差別是會不停「遞增上去」。
舉例來說,假設我原本有 3 個欄位,現在動態刪除了 1 個欄位,接著再新增 1 個欄位,fields 的內容會變這樣:
他不像 name
一樣會自動「倒退回去」,而是不停的遞增上去來確保「唯一性」。仔細想想就會覺得這也挺合理的,畢竟是 key 嘛?
這邊也稍微複雜一點,不懂的話到 這邊 自己玩玩看。
operation
這個就比較好理解一些了,簡單來說就是物件中有三個 function:
add(defaultValue?: any, insertIndex?: number)
新增一筆欄位(初始值 & 插入位置)remove(index: number | number[])
傳入指定的值來把欄位刪除(通常會傳field.name
)move: (from: number, to: number)
移動欄位的位置
meta
這個是搭配 Form.ErrorList
使用的東西,但我看不太懂官方的 範例 是什麼意思。總之這個應該不太常會用到,只要知道一下是跟錯誤有關的東西就行了。
總之以上看完後你應該就對 Form.List
有一定的理解了,剩下的就多練習吧。
另外如果你想要的是比較單純的資料,像這樣:
1 | { |
可以參考我寫的簡化版範例