调用Handlebars助手后无法访问数组元素问题排查
解决Handlebars自定义助手
if_greater中无法访问数组元素的问题 我懂你卡在哪了——用了自定义的if_greater助手后,模板里的{{this.date}}这类数组元素属性突然访问不了了。这事儿的核心原因其实是你用箭头函数定义助手,搞丢了模板的上下文(this)。
问题根源
Handlebars在调用自定义助手时,会把当前模板的上下文(比如{{#each}}循环里的单个数组元素)绑定到助手函数的this上。但你用了箭头函数来写助手,箭头函数不会绑定自己的this,它的this是继承自外层作用域的,根本不是你需要的数组项对象。这就导致你在opts.fn(this)里传的this完全不对,模板自然找不到date、serial这些属性。
修复方案
这里给你两种最直接的解决办法,优先选第一种:
方案1:把箭头函数改成普通函数(最推荐)
只要把助手的箭头函数换成普通函数,Handlebars就能自动把当前数组项的上下文绑定到助手的this上,问题直接解决:
// 替换箭头函数为普通函数 hbs.registerHelper('if_greater', function(a, b, opts) { if (a >= b) { return opts.fn(this); // 这里的this就是当前数组项 } return opts.inverse(this); });
改完之后,模板里的{{this.date}}就能正确访问数组元素的属性了,因为opts.fn(this)把正确的上下文传递给了块内容。
方案2:手动传递上下文(迫不得已时用)
如果因为某些限制必须用箭头函数,可以通过opts.data手动获取模板上下文:
hbs.registerHelper('if_greater', (a, b, opts) => { // 从opts.data中拿到当前模板的上下文 const currentContext = opts.data.root; if (a >= b) { return opts.fn(currentContext); } return opts.inverse(currentContext); });
不过这种方式不如方案1省心,要是在多层嵌套的模板里,还得额外处理上下文层级,所以优先用方案1。
模板调用小提醒
确保你是在数组循环(比如{{#each}})里使用这个助手,比如:
{{#each yourDataList}} {{#if_greater 20 occurrences}} <tr class="danger"> <td>{{this.date}}</td> <td>{{this.serial}}</td> <!-- 其他属性渲染 --> </tr> {{else}} <!-- 不符合条件时的内容 --> {{/if_greater}} {{/each}}
这里的occurrences如果是当前数组项的属性,直接写就行(因为each内部的上下文就是单个元素);如果是全局变量,也没问题。
验证一下
把助手改成普通函数后重启应用,模板里的数组元素属性应该就能正常渲染了。
内容的提问来源于stack exchange,提问作者tomislaaav
相关产品推荐
相关产品推荐

