iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 17
0
Modern Web

用 JavaScript 打造全端產品的入門學習筆記系列 第 17

資料操作 CRUD 功能:實作修改、刪除——經典全端實務 IV

CRUD-Update, Delete

本筆記將接續 前篇,將以 Todo List 為例,用五大步驟進一步拆解「更新」、「刪除」兩大常見功能的開發歷程,然而資料庫本身提供不只一種能達成目的的操作方法,本筆記僅提供其中之一,想深入研究者可以自行查閱 官方文件

 

更新 Update

Update 運作機制

Update 運作機制 edit from Alpha Camp's material

1. 客戶端 Client:觸發請求的機制

更新 Todo 使用者流程

更新 Todo 使用者流程 from Alpha Camp's material

根據使用者流程設計,觸發機制分別為首頁(index)及細節頁面(detail) 的「編輯按鈕」,並由此導向「編輯表單頁(edit)」。

由於從首頁連至 edit 頁面的流程與導向首頁或新增表單頁類似,這邊直接從送出 edit 表單開始拆解。

<form action="/todos/{{ todo._id }}/edit" method="POST">
  <input type="text" placeholder="name" name="name" value="{{ todo.name }}">
  <button type="submit">Save</button>
  <a href="/">back</a>
</form>

其中兩點特別要注意:

  1. 由於 HTML form 預設只能使用 GET 及 POST method,然而 Restful 路由設計會採用 PUT,所以在重構的時候會再導入套件來優化。
  2. 為了優化使用者體驗,會在 <input> 保留原始的資料 value="{{ todo.name }}"

2. 路由 Route:接收請求的路由

前面提到 method 的部分之後才會優化,目前會先以 POST 搭配 path /edit 來設計:

app.post('/todos/:id/edit', (req, res) => {
  const { id } = req.params // 從 URL 的 path 取得 id
  const update = req.body   // 藉 body-parser 拿到更新的內容
  // ...
}

3,4,5. 伺服器內部的 MVC

特別說明使用 Model.findByIdAndUpdate() 的好處是:可以傳入物件參數 update 一次更新一筆資料中的多個部分,而不用逐項修改。並且可選擇性加入其他參數。其中的 { new: true } 意思是優先存入最新的版本。細節請參考 Model.findByIdAndUpdate() 官方文件

// Controller:路由內的邏輯都是分派程序
app.post('/todos/:id/edit', (req, res) => {
  const { id } = req.params
  const update = req.body
  return Todo.findByIdAndUpdate(id, update, { new: true }) // Model:找到該 id 的 todo,並且以新的物件覆蓋更動的部分。
    .then(()=> res.redirect(`/todos/${id}`))               // View:新增完成後導回細節頁面
    .catch(error => console.log(error))
}

 

刪除 Delete

Delete 運作機制

Delete 運作機制 edit from Alpha Camp's material

1. 客戶端 Client:觸發請求的機制

刪除 Todo 使用者流程

刪除 Todo 使用者流程 from Alpha Camp's material

在首頁(index)及細節頁面(detail)都有刪除按鈕,觸發位置雖然不同,但將導向同一路由。由於 Delete 無法用 GET 傳遞,故採用 form。且前面提到 HTML 元件目前不支援 GET、POST 外的 method,所以也是之後來優化。

<!-- detail.hbs -->
<p>{{ todo.name }}</p>
<a href="/todos/{{ todo._id }}/edit">edit</a>
<a href="/">back</a>

<!-- 刪除僅能以 form 來送出 -->
<form action="/todos/{{ todo._id }}/delete" method="POST" style="display: inline;">
  <button type="submit">delete</button>
</form>

2. 路由 Route:接收請求的路由

先以 POST 搭配 path /delete 來設計:

app.post('/todos/:id/delete', (req, res) => {
  const id = req.params.id // 存取 URL path 上的 id 
  // ...
})

3,4,5. 伺服器內部的 MVC

使用 Model.findByIdAndDelete() 可以找到符合 id 的資料,直接刪除,細節可以參考 Model.findByIdAndDelete() 官方文件

// Controller:路由內的邏輯都是分派程序
app.post('/todos/:id/delete', (req, res) => {
  const id = req.params.id
  return Todo.findByIdAndDelete(id) // Model:找到該 id 的 todo,並且從資料庫中刪除。
    .then(() => res.redirect('/'))  // View:導回首頁 index
    .catch(error => console.log(error))
})

 


閱讀更多

Infinite Gamer
關於本系列更多內容及導讀,請閱讀作者於 Medium 個人專欄 【無限賽局玩家 Infinite Gamer | Publication – 】 上的文章 《用 JavaScript 打造全端產品的入門學習筆記》系列指南


上一篇
資料操作 CRUD 功能:實作新增、讀取——經典全端實務 III
下一篇
強化功能:排序 sort、篩選 filter——經典全端實務 V
系列文
用 JavaScript 打造全端產品的入門學習筆記30

尚未有邦友留言

立即登入留言