「Express Handlebars 取得父層變數內容」相關筆記
問題描述
- 情境:在 express-handlebars 中使用原生的
each
搭配 handlebars-helpers 的is
進行條件判斷,進而渲染出一組<select>
<select>
中的每一個<option>
都是一種餐廳類型(舉例:日本料理、酒吧、美式餐廳等)- (由
app.js
傳遞給edit.handlebars
的變數)categories
為餐廳類型的陣列資料,restaurant
為物件變數,可透過restaurant.category
來取得該餐廳的餐廳類型 - 當
each
迴圈中this
的值與restaurant.category
一致時,pre-selected 該<option>
- 問題:檢查最終的 DOM 內容,發現並沒有渲染出應該要預先被選擇的
<option>
- 行為不如預期的原始碼:
// app.js端 app.get('/restaurants/:id/edit', (req, res) => { const id = Number(req.params.id) const targetRestaurant = restaurantList.results.find((restaurant) => restaurant.id === id) const categories = [] restaurantList.results.forEach(restaurant => { if (!categories.includes(restaurant.category)) { categories.push(restaurant.category) } }) res.render('edit', { restaurant: targetRestaurant, categories }) })
<!-- handlebars端 --> {{#each categories}} {{#is this restaurant.category)}} <option value="{{this}}" selected>{{this}}</option> {{else}} <option value="{{this}}">{{this}}</option> {{/is}} {{/each}}
環境
express-handlebars: 5.3.2
handlebars-helpers: 0.10.0
解決方式
將 handlebars 端的內容修改如下(restaurant.category
加上../
):
<!-- handlebars端 -->
{{#each categories}}
{{#is this ../restaurant.category)}}
<option value="{{this}}" selected>{{this}}</option>
{{else}}
<option value="{{this}}">{{this}}</option>
{{/is}}
{{/each}}
參考 Handlebars 官方文件的說明:
Some helpers like
#with
and#each
allow you to dive into nested objects. When you include../
segments in your path, Handlebars will change back into the parent context.
在巢狀結構中,使用../
來取得上一層變數的內容