Nodejs Handlebars中使用{{#each}}遍历两个独立数组的方法
问题根源
这是Handlebars作用域规则导致的典型问题,和数据库返回的RowDataPacket数据结构无关:
- Handlebars的
{{#each}}块助手会切换当前上下文:进入{{#each parametro}}循环后,块内的this指向parametro数组里的单条记录,此时直接写tipoParametros,会尝试读取当前单条记录上的tipoParametros属性,这个属性不存在,自然拿不到数据。 - 调用局部模板
{{> formparametro}}时,默认会把当前所在位置的上下文传给局部模板。你是在parametro的循环内部调用的局部模板,传给partial的上下文只有单条parametro的字段,根本没有你在res.render时传入的根级tipoParametros数组,所以遍历不到任何内容。
修复方法
只需要调整模板里的变量引用和局部模板传参逻辑即可:
- 首先修改主视图(parametros/modificar.hbs)里的循环和局部模板调用代码,通过Handlebars内置的
@root引用直接拿到渲染时传入的根级数据,显式把tipoParametros传给局部模板:
{{#each parametro}} <form class="row g-3 needs-validation" method="POST" action="/parametros/modificar/{{this.parid}}" novalidate> {{! 显式将根级的tipoParametros传入局部模板,同时传入当前参数的类型id用于下拉默认选中 }} {{> formparametro tipoParametros=@root.tipoParametros selectedTipoparid=this.tipoparid}} </form> {{/each}}
- 局部模板
formparametro里的下拉框不需要调整遍历逻辑,直接就能拿到传入的tipoParametros数组完成渲染,还可以顺便加上默认选中逻辑(如果没装handlebars-helpers助手包,可以去掉selected相关判断,不影响选项渲染):
<div class="col-6"> <div class="form-floating"> <select class="form-select" id="floatingSelect" name="tipoparid" aria-label="Floating label select example" required> {{#each tipoParametros}} <option value="{{this.tipoparid}}" {{#if (eq this.tipoparid ../selectedTipoparid)}}selected{{/if}}> {{this.tipoparcodigo}} </option> {{/each}} </select> <label for="floatingSelect">Tipo Parametro</label> </div> </div>
可选简化写法
如果不想每次给局部模板传零散参数,也可以在调用局部模板时直接把根上下文作为partial的上下文,同时把当前循环的parametro对象单独传入:
{{#each parametro}} <form class="row g-3 needs-validation" method="POST" action="/parametros/modificar/{{this.parid}}" novalidate> {{! 把@root作为局部模板的上下文,单独传当前循环的参数对象 }} {{> formparametro currentItem=this}} </form> {{/each}}
这种写法下局部模板内可以直接访问根级的tipoParametros,需要用到当前parametro的字段时,通过{{currentItem.xxx}}取值即可。
注:mysql2返回的RowDataPacket实例可以被Handlebars正常读取属性,不需要额外做JSON转普通对象的操作。
内容的提问来源于stack exchange,提问作者Marlon Miller
相关产品推荐
相关产品推荐

