本筆記將接續 前篇,將以 Todo List 為例,用五大步驟進一步拆解「新增」、「讀取」兩大常見功能的開發歷程,然而資料庫本身提供不只一種能達成目的的操作方法,本筆記僅提供其中之一,想深入研究者可以自行查閱 官方文件。
依據使用者流程,觸發新增的機制分為兩步驟
<a href="./todos/new">Create</a>
<!-- 新增表單 new.hbs -->
<form action="/todos/new" method="POST">
<input type="text" placeholder="name" name="name">
<button type="submit">Create</button>
</form>
接著針對送出表單的路由來分析(導向 new 新增表單頁面的流程會更簡單,不需操作資料庫),表單資料會使用 body-parser 套件來接收:
// 引用並設定 body-parser
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: true }))
// 設定「新增表單」的路由
app.post('/todos/new', (req, res) => {
const { name } = req.body // 接收表單提供的資料
// ...
})
通常 MVC 的程序邏輯都會放在路由內部;除非程序過於複雜,就會打包成函式存放在其他檔案中管理。
// Controller:路由內的邏輯都是分派程序
app.post('/todos', (req, res) => {
const { name } = req.body
Todo.create({ name }) // Model:以此資料新增進資料庫中
.then(() => res.redirect('/')) // View:新增完成後導回首頁
.catch(error => console.error(error))
})
新增的最後一步是導回首頁:流程為「向伺服器請求全部 Todos,並羅列在頁面上」。
<!-- 首頁 index.hbs -->
<a href="./todos/new">Create</a>
<ul>
{{#each todos}}
<li>
{{this.name}}
</li>
{{/each}}
</ul>
根據使用者流程,觸發機制為:點選 detail 連結後,在 detail 呈現特定 Todo。
<!-- 首頁 index.hbs -->
<a href="./todos/new">Create</a>
<ul>
{{#each todos}}
<li>
{{this.name}}
<!-- 新增 detail 頁連結 -->
<a href="./todos/{{ this._id }}">detail</a>
</li>
{{/each}}
</ul>
這裡使用「動態路由」來顯示各個不同的 Todo 並以 id 做為確認機制,以 params 來接收 id
app.get('/todos/:id', (req, res) => {
const { id } = req.params // 接收 URL 的動態 path
// ...
})
Controller 將透過 Model 拿到 id 與輸入值相同的 Todo,並且藉由 View 渲染在 detail 頁面上:
// Controller:路由內的邏輯都是分派程序
app.get('/todos/:id', (req, res) => {
const { id } = req.params
Todo.findById(id) // Model:以 id 在資料庫中搜尋 Todo
.lean() // Model:取出實際可被運用的資料
.then((todo) => res.render('detail', { todo })) // View:將提取到的 Todo 渲染進 detail 頁面
.catch(error => console.error(error))
})
<!-- 細節頁面 detail.hbs -->
<p>{{ todo.name }}</p>
<a href="/">back</a>
關於本系列更多內容及導讀,請閱讀作者於 Medium 個人專欄 【無限賽局玩家 Infinite Gamer | Publication – 】 上的文章 《用 JavaScript 打造全端產品的入門學習筆記》系列指南。