如何解决Mongoose获取的MongoDB子文档_id传入EJS时报错的问题
问题根因
你遇到的问题有两个核心原因:
- 直接通过Mongoose查询拿到的子文档是被代理的Mongoose文档实例,不是普通JS对象,内部属性受Mongoose管控,直接修改、删除属性都不会生效
- ObjectId类型的
_id传递到EJS后,如果直接在<script>标签中使用,没有被包裹为合法字符串的话就会触发语法错误
可行解决方案
方案1:将子文档转为普通JS对象后再处理
这是最通用的方案,转成普通对象后可以随意修改或删除字段:
Hiker.findById(id, (err, hiker) => { const hike = hiker.log.id(hikeId) // 调用toObject()转为普通JS对象,解除Mongoose代理 const plainHike = hike.toObject() // 转为字符串 plainHike._id = plainHike._id.toHexString() // 如果要删除字段直接用:delete plainHike._id res.render('editHike', { data: plainHike }) })
方案2:查询时直接返回普通对象
查询时加上lean()方法,整个查询结果都会返回纯JS对象,不需要额外转换:
// 加lean() + exec() 拿到纯JS格式的查询结果 Hiker.findById(id).lean().exec((err, hiker) => { const hike = hiker.log.find(item => item._id == hikeId) // 此时hike已经是普通对象,可直接修改 hike._id = hike._id.toString() res.render('editHike', { data: hike }) })
方案3:直接在EJS侧处理
如果不想修改后端逻辑,也可以在EJS中使用时做兼容,尤其是在<script>标签中使用时一定要加引号包裹:
<!-- 普通场景直接使用 --> <p>徒步记录ID:<%= data._id %></p> <!-- JS脚本中使用 --> <script> // 外层加单引号把ObjectId转为字符串,避免语法错误 const hikeId = '<%= data._id %>' // 也可以主动调用转字符串方法 const hikeId = '<%= data._id.toString() %>' </script>
内容的提问来源于stack exchange,提问作者Alpine_Shell
相关产品推荐
相关产品推荐

