SuiteScript 2.1自定义数据源在Freemarker模板中遍历对象键失败
在NetSuite Suitelet的Freemarker模板中无法遍历自定义数据源对象键的解决方法
问题背景
在Suitelet中通过renderer.addCustomDataSource传入自定义数据后,能通过具体路径(如${obj.transactions.EUR[0].total})访问数据,但无法用Freemarker的?keys指令遍历对象的键;模板内自行创建的哈希对象却能正常遍历,且已尝试render.DataSource.JSON和render.DataSource.OBJECT两种格式均无效。
原因分析
NetSuite对Freemarker的渲染环境做了封装限制:通过自定义数据源传入的对象会被转换为NetSuite内部的哈希结构(而非Freemarker原生的SimpleHash),这种封装后的对象不支持?keys、?values这类原生遍历指令,导致无法直接遍历对象键。
解决方案
方案一:在Suitelet中提前提取对象键数组
在传入数据源前,手动提取目标对象的键并作为单独字段传入,模板直接遍历该数组即可:
修改后的Suitelet代码
const obj1 = { currency: "EUR Currency", transactions: { EUR: [ { parent_transaction: "101", total: "31.00" }, { parent_transaction: "202", total: "650.00" }, { parent_transaction: "303", total: "50.00" } ], USD: [ { parent_transaction: "2", total: "32221.00" }, { parent_transaction: "3", total: "64250.00" } ] }, // 新增:提取transactions的键数组 transactionCurrencies: Object.keys(obj1.transactions) }; // 使用OBJECT格式传入,无需JSON.stringify renderer.addCustomDataSource({ format: render.DataSource.OBJECT, alias: 'obj', data: obj1 });
修改后的Freemarker模板
<div> <#list obj.transactionCurrencies as currency> <h2>${currency}</h2> <table border="1"> <thead> <tr> <th>Parent Transaction</th> <th>Total</th> </tr> </thead> <tbody> <#list obj.transactions[currency] as transaction> <tr> <td>${transaction.parent_transaction}</td> <td>${transaction.total}</td> </tr> </#list> </tbody> </table> </#list> </div>
方案二:在模板中用?eval转换为原生哈希
若坚持使用JSON格式的数据源,可在模板中将封装后的对象转换为Freemarker原生可遍历的结构(需确保数据安全,无注入风险):
修改后的Freemarker模板
<div> <!-- 将NetSuite封装的对象转换为原生哈希 --> <#assign transactions = obj.transactions?eval> <#list transactions?keys as currency> <h2>${currency}</h2> <table border="1"> <thead> <tr> <th>Parent Transaction</th> <th>Total</th> </tr> </thead> <tbody> <#list transactions[currency] as transaction> <tr> <td>${transaction.parent_transaction}</td> <td>${transaction.total}</td> </tr> </#list> </tbody> </table> </#list> </div>
补充说明
模板内自行创建的哈希对象属于Freemarker原生SimpleHash,因此支持?keys遍历;而自定义数据源的对象经过NetSuite封装,丢失了原生遍历能力,这是两种场景表现不同的核心原因。
内容的提问来源于stack exchange,提问作者jjoht
相关产品推荐
相关产品推荐

