You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:22:39