如何在Handlebars中根据ID存在状态禁用属性?附Node.js路由场景
解决方案
看起来你需要在Handlebars模板里根据StateResult的已有数据来禁用对应的选举单元选项,我来帮你梳理两种可行的实现方式,先从优化后端数据处理开始,让模板逻辑更简洁。
第一步:优化后端路由(推荐方案)
原来的嵌套then写法有点像回调地狱,我们可以用async/await重构,同时提前给每个选举单元标记是否需要禁用,这样前端模板不用做复杂判断:
router.get('/', async (req, res) => { try { // 并行获取所有数据,比串行请求更高效 const [stateResults, electoralUnits, stateLists] = await Promise.all([ StateResult.find({}), ElectoralUnit.find({}), StateList.find({}) ]); // 提取所有已存在于StateResult中的选举单元ID(注意转成字符串,避免ObjectId类型不匹配) const processedIds = stateResults.map(result => result.electoralUnitId.toString()); // 这里假设StateResult存储选举单元ID的字段是electoralUnitId,你可以根据实际字段名调整 // 给每个选举单元添加isDisabled标记 const readyElectoralUnits = electoralUnits.map(unit => ({ ...unit.toObject(), // 把Mongoose文档转为普通JS对象 isDisabled: processedIds.includes(unit._id.toString()) })); res.render('home/results/stateResults', { stateResults, electoralUnits: readyElectoralUnits, stateLists }); } catch (err) { console.error(err); res.status(500).send('服务器加载数据失败'); } });
第二步:Handlebars模板中实现禁用逻辑
现在每个选举单元都自带了isDisabled属性,直接在模板里判断即可:
示例1:下拉选择框场景
<select name="electoralUnit"> {{#each electoralUnits}} <option value="{{_id}}" {{#if isDisabled}}disabled{{/if}}> {{name}} {{#if isDisabled}}(已有结果,不可选){{/if}} </option> {{/each}} </select>
示例2:列表按钮场景
{{#each electoralUnits}} <div class="unit-item"> <span>{{name}}</span> <button {{#if isDisabled}}disabled{{/if}}> {{#if isDisabled}}已处理{{else}}添加结果{{/if}} </button> </div> {{/each}}
备选方案:使用Handlebars自定义Helper
如果不想在后端处理数据,也可以注册一个自定义Helper来做ID存在性判断:
1. 先在Express配置中注册Helper
const express = require('express'); const exphbs = require('express-handlebars'); const app = express(); const hbs = exphbs.create({ helpers: { // 自定义判断数组是否包含指定值的Helper includes: function(array, value) { return array.includes(value.toString()); } } }); app.engine('handlebars', hbs.engine); app.set('view engine', 'handlebars');
2. 路由中传递已存在的ID数组
router.get('/', async (req, res) => { try { const [stateResults, electoralUnits, stateLists] = await Promise.all([ StateResult.find({}), ElectoralUnit.find({}), StateList.find({}) ]); const existingIds = stateResults.map(r => r.electoralUnitId.toString()); res.render('home/results/stateResults', { stateResults, electoralUnits, stateLists, existingIds }); } catch (err) { console.error(err); res.status(500).send('服务器加载数据失败'); } });
3. 模板中使用Helper判断
<select name="electoralUnit"> {{#each electoralUnits}} <option value="{{_id}}" {{#if (includes ../existingIds _id)}}disabled{{/if}}> {{name}} </option> {{/each}} </select>
关键注意点
- 一定要把Mongoose的
ObjectId转成字符串再对比,不然会因为类型不匹配导致判断失效; - 如果用第一种后端标记的方案,记得调用
toObject()把Mongoose文档转成普通对象,否则模板可能无法访问新增的isDisabled属性。
内容的提问来源于stack exchange,提问作者Nenad M
相关产品推荐
相关产品推荐

