You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:50:59