使用nodemailer-express-handlebars时,如何正确向Handlebars助手传递数组?
解决nodemailer-express-handlebars中{{#each}}块不渲染的问题
核心错误分析
你的代码存在两个关键问题,导致{{#each}}无法正常渲染内容:
数据传递层级错误
你的请求体本身就是包含lineItems数组的对象,但你直接将req.body赋值给了lineItems变量,最终传递给模板的context.lineItems变成了整个请求体对象,而非预期的数组。模板内注册Helper无效
邮件模板中的<script>代码在服务器端编译时不会执行,Handlebars Helper必须在Node.js代码层面注册。而且Handlebars默认自带eachHelper,完全不需要自定义。
修复步骤
1. 修正数据传递逻辑
修改JS代码中lineItems的赋值语句,从请求体里提取真正的数组:
// 原错误代码 const lineItems = req.body; // 修改为 const lineItems = req.body.lineItems;
2. 移除模板内无效的Helper注册代码
删除index.hbs头部的<script>块,这部分代码不会被执行,且自带的each Helper已经足够使用:
<!-- 删除以下无效代码 --> <script> Handlebars.registerHelper("each", function(context, options) { var ret = ""; for (var i = 0, j = context.length; i < j; i++) { ret = ret + options.fn(context[i]); } return ret; }); </script>
3. 确认模板变量引用正确
你的模板内变量引用逻辑是正确的,在{{#each lineItems}}块内,直接使用{{lineItemUrl}}、{{lineItemName}}即可访问数组元素的属性,无需额外前缀。
修改后的完整JS代码片段
const hbs = require('nodemailer-express-handlebars'); const nodemailer = require('nodemailer'); const path = require('path'); const Handlebars = require("handlebars"); const viewPath = path.resolve(__dirname, './templates/views/'); const partialsPath = path.resolve(__dirname, './templates/partials'); function reviewMail(req){ // 修正:提取请求体中的lineItems数组 const lineItems = req.body.lineItems; var transport = nodemailer.createTransport({ host: "HOST", port: 587, auth: { user: "USER", pass: "PASS" } }); transport.use('compile', hbs({ viewEngine: { extName: '.hbs', layoutsDir: viewPath, defaultLayout: false, partialsDir: partialsPath, }, viewPath: viewPath, extName: '.hbs', })) var mailOptions = { from: 'MAIL', to: 'MAIL', subject: 'Bitte bewerte deine Bestellung', template: 'index', context: { lineItems: lineItems } }; transport.sendMail(mailOptions, (error, info) => { if (error) { return console.log(error); } console.log('Message sent: %s', info.messageId); }); }; module.exports = { reviewMail }
修改后的模板核心代码
{{#each lineItems}} <!-- HTML Code --> <a href="{{lineItemUrl}}"><img class="adapt-img" src="{{lineItemImage}}">{{lineItemName}}</a> <!-- HTML Code --> {{/each}}
内容的提问来源于stack exchange,提问作者Yannick Gallist
相关产品推荐
相关产品推荐

