Handlebars eq函数匹配MongoDB ObjectId失效问题求助
解决Handlebars中eq判断Mongoose ObjectID不生效的问题
问题根源
你看到两个ID显示完全一致,但实际一个是Mongoose ObjectID对象,另一个要么是字符串,要么是另一个ObjectID实例——Handlebars自带的eq助手做的是严格相等比较(===),对象实例不同就算值一样,也会判定不相等,这就是条件不触发的原因。
两种可行解决方案
方案1:后端把ObjectID转成字符串
在Express路由的查询逻辑里,直接让Mongoose返回普通JS对象(而非文档实例),这样_id会自动转为字符串:
// 修改你的Express路由查询代码 router.get('/your-path', async (req, res) => { // 用.lean()获取普通JS对象,_id自动变为字符串格式 const league = await League.findOne({/* 你的查询条件 */}).lean(); res.render('your-template', { league }); });
如果不想用.lean(),也可以手动遍历转换:
league.groupNo1 = league.groupNo1.map(item => { return { ...item, _id: item._id.toString() }; });
方案2:自定义Handlebars比较助手
如果不想改动后端逻辑,直接给Handlebars加一个专门处理ObjectID比较的自定义助手:
// 在Handlebars注册代码里添加 const handlebars = require('handlebars'); handlebars.registerHelper('eqId', function(id1, id2, options) { // 处理空值,统一转成字符串再比较 const strId1 = id1 ? id1.toString() : ''; const strId2 = id2 ? id2.toString() : ''; return strId1 === strId2 ? options.fn(this) : options.inverse(this); });
然后在模板里替换原来的eq为自定义的eqId:
{{#each teams}} {{#eqId _id ../league.groupNo1.[0]._id}} Warning! {{teamName}} {{else}} {{teamName}} {{/eqId}} {{/each}}
关于lookup报错的说明
lookup助手是用来按键名获取对象属性的(比如{{lookup user "name"}}等价于user.name),根本不是用来做相等判断的工具,所以用它来比较ID肯定会报错,别再用它处理这个场景了。
内容的提问来源于stack exchange,提问作者atuna00
相关产品推荐
相关产品推荐

