編輯資料的操作行為可以分為 3 個部分: 1. 編輯的畫面操作:點擊按鈕,切換 input 編輯框顯示 2. 編輯的函式說明 3. 編輯資料 API 使用 PUT 以下為此 3 部分的程式碼邏輯與說明: ## 1. 編輯的畫面操作:點擊按鈕,切換 input 編輯框顯示 首先拿到資料的時候,會將所有的資料加上 `isEditing`: ``` const getTodos = async () => { try { const response = await axios.get(`${api}/todos`, { headers: { Authorization: token }, }); setTodos(response.data.data.map(todo => ({ ...todo, isEditing: false }))); } catch (error) { console.error("取得資料失敗", error); } }; ``` ![HitPawOnline_222714](https://hackmd.io/_uploads/rJKA87HFA.gif) 這個 ```isEditiong``` 是用來判斷是否有點擊編輯按鈕。 所以當點擊編輯按鈕時,會透過 ```isEditiong``` 等於 ```true``` 的方式來展開 ``` {item.isEditing ? ( <> <input type="text" value={editTodo[item.id] || item.content} onChange={(e) => onEditInputChange(e, item.id)} /> <button onClick={() => saveTodo(item)} className="btn btn-primary ms-1">保存</button> <button onClick={() => cancelEdit(item.id)} className="btn btn-danger ms-1">取消編輯</button> </> ) : ( <> {item.content} <button onClick={() => editTodoItem(item.id)} className="btn btn-secondary ms-1">編輯</button> </> )} ``` --- ## 2. 編輯的函式說明 點擊編輯按鈕展開之後,主要會三個 function,分別是: ```onEditInputChange```、```saveTodo(item)```、```cancelEdit(index)``` * ### onEditInputChange:監聽 input 發生變化時,會將更新值存放在暫存區 ![HitPawOnline_223253](https://hackmd.io/_uploads/Sy0bcmBKA.gif) ``` const onEditInputChange = (event, id) => { setEditTodo({ ...editTodo, [id]: event.target.value, }); }; ``` 值得注意的是這裡多加了一個 id 的屬性,原因是我們會利用陣列 + id 索引的方式來呈現該筆資料 ``` <input type="text" value={editTodo[item.id] || item.content} onChange={(e) => onEditInputChange(e, item.id)} /> ``` 所以一定要加上 id,才能正確地呈現每筆資料。 * ### saveTodo:按下保存之後會把資料傳送到後端去。 ![HitPawOnline_224756](https://hackmd.io/_uploads/BkMgCQSKR.gif) * ### cancelEdit:關閉編輯模式。 ![螢幕錄影 2024-07-29 晚上10.58.22](https://hackmd.io/_uploads/SJBu1VrYA.gif) ## 編輯資料 API 使用 PUT 編輯資料會使用到 `PUT` 的方式,我們會先帶入產品的 id, 接著在後方 data 帶入需要更改的資料內容 ```js const url = "example/api" axios.put(`${url}/${ 要更新產品的id }`, data, { headers: { Authorization: token.value, }, }) .then(response => { console.log('資料更新成功:', response.data); }) .catch(error => { console.error('更新資料時發生錯誤:', error); }); ``` 題目 --- 了解編輯的資料處理邏輯後,請操作 [這個模板](https://codepen.io/yen-kg/pen/NWQMmbb?editors=1010),執行以下要求: * 請完成 saveTodo 編輯資料的功能,並且當按下保存時,會關閉編輯模式,然後更新畫面。 備註:[詳細可以參考 API 文件](https://todolist-api.hexschool.io/doc/#/%E4%BB%A3%E8%BE%A6%E4%BA%8B%E9%A0%85/patch_todos__id__toggle) ## 回報流程 將答案寫在 CodePen 並複製 CodePen 連結貼至底下回報就算完成了喔! 解答位置請參考下圖(需打開程式碼的部分觀看) ![](https://i.imgur.com/vftL5i0.png) <!-- 解答: const saveTodo = async (item) => { const updatedContent = editTodo[item.id] || item.content; try { await axios.put(`${api}/todos/${item.id}`, { content: updatedContent }, { headers: { Authorization: token }, }); setTodos(todos.map(todo => todo.id === item.id ? { ...todo, content: updatedContent, isEditing: false } : todo )); } catch (error) { console.error("保存資料失敗", error); } }; --> 回報區 --- | Discord | CodePen / 答案 | |:----------------:|:-------------------------------------------------------------------:| | Sonia | [CodePen](https://codepen.io/YUJOU/pen/mybBoex?editors=0011) | | tim | [CodePen](https://codepen.io/jskrtivy-the-animator/pen/MYgEmxg?editors=0011) | |Hailey|[CodePen](https://codepen.io/sxbokfja-the-flexboxer/pen/NPKwxQg)| | 毛巾 |[CodePen](https://codepen.io/bqdcjboa-the-solid/pen/MYgOygX)| | Noy(Toad) |[Codepen](https://codepen.io/MochiCodingPen/pen/ByBmjVz) | | Jasmine | [CodePen](https://codepen.io/Jasmine-Lin-the-vuer/pen/GgKOoVZ) | | 4chan | [CodePen](https://codepen.io/ijuolaqc-the-looper/pen/JoPOXyj) | | Toung | [CodePen](https://codepen.io/Toung/pen/MYgOKPQ) | | Yen | [CodePen](https://codepen.io/yuxxxlouyen/pen/GgKOZwM) | | Nocab | [CodePen](https://codepen.io/PeihanWang/pen/QwLOGez?editors=1011) | | 爆漿 | [CodePen](https://codepen.io/nvdwwlbx-the-vuer/pen/azoVGzV?editors=1011) | | 蕾蕾 leilei | [CodePen](https://codepen.io/Leileisme/pen/jENaxKB?editors=1111) | | Johnson | [CodePen](https://codepen.io/crpbugqy-the-typescripter/pen/wBwPRMw) | | 泊岸 | [CodePen](https://codepen.io/qoq77416416/pen/wBwpvQO?editors=1010) | | LinaChen | [CodePen](https://codepen.io/LinaChen/pen/YPKYzBL) | |邵|[CodePen](https://codepen.io/ukscrlno-the-typescripter/pen/mybpVjN?editors=1011)| | Amanda | [CodePen](https://codepen.io/cym199922/pen/qEWpoqN) | | Kaya | [CodePen](https://codepen.io/kayaribi/pen/dPbJKYE) | | Fabio20 | [CodePen](https://codepen.io/fabio7621/pen/WbedgoN?editors=1010) | | Satar | [CodePen](https://codepen.io/SatarKuo/pen/yyBpypM?editors=0011) | | 嚼勁先生 | [CodePen](https://codepen.io/James520284/pen/azoqzGE) | | mercury2508. |[CodePen](https://codepen.io/Mercury2508/pen/VYZXrww)| | Rochel | [Codepen](https://codepen.io/rochelwang1205/pen/bNbKoxG)| | yun-lin | [CodePen](https://codepen.io/yunlinhsu/pen/azoejPK?editors=1011) | | KOMATSU PEI | [CodePen](https://codepen.io/Komatsu2021/pen/azbLaRN?editors=0010) | | 姜承 | [CodePen](https://codepen.io/Troy0718/pen/YPzvLwa?editors=1010) | | chris | [CodePen](https://codepen.io/chris-chen-the-selector/pen/wBvRXaj?editors=1011) | <!-- | user | [CodePen]() | -->