如何用Handlebars基于含动态日期键的对象数组生成表格?
解决Handlebars动态日期键的表格渲染问题
问题场景
现有如下动态对象数组,其中日期键名不固定:
const arr = [ { user: 'b@b.com', name: 'b', surname: 'b', '29_07_2022': 'YES', '01_08_2022': 'YES', '11_11_2022': 'YES' }, { user: 'c@c.com', name: 'c', surname: 'c', '29_07_2022': 'YES', '01_08_2022': 'NO', '11_11_2022': 'NO' } ];
需要用Handlebars渲染成包含动态日期列的表格,但无法直接访问未知的日期键值。
解决方案
1. 预处理数据(推荐)
在渲染前先把数据转换为更适合Handlebars遍历的结构:提取所有日期字段作为表头,同时给每个用户对象添加日期键值对数组。
// 提取所有唯一的日期键(假设所有用户的日期键一致) const dateKeys = Object.keys(arr[0]).filter(key => key.match(/^\d{2}_\d{2}_\d{4}$/)); // 转换每个用户对象 const processedData = arr.map(user => { const dates = dateKeys.map(key => ({ date: key, value: user[key] })); return { ...user, dates }; }); // 准备传给Handlebars的上下文 const context = { dateHeaders: dateKeys, users: processedData };
2. 修改Handlebars模板
用处理后的上下文渲染表格,遍历日期表头和每个用户的日期值:
<table style="width:100%"> <tr> <th>USER</th> <th>NAME</th> <th>SURNAME</th> {{#each dateHeaders}} <th>{{this}}</th> <!-- 如需格式化日期,可直接在预处理时转换为目标格式 --> {{/each}} </tr> {{#each users}} <tr> <td>{{user}}</td> <td>{{name}}</td> <td>{{surname}}</td> {{#each dates}} <td>{{value}}</td> {{/each}} </tr> {{/each}} </table>
备选方案:自定义Handlebars Helper
如果不想预处理数据,可以自定义一个helper来遍历对象的动态字段:
Handlebars.registerHelper('eachDynamic', function(obj, options) { const fixedKeys = ['user', 'name', 'surname']; let output = ''; Object.keys(obj).forEach(key => { if (!fixedKeys.includes(key)) { output += options.fn({ key: key, value: obj[key] }); } }); return output; });
模板中使用该helper:
<table style="width:100%"> <tr> <th>USER</th> <th>NAME</th> <th>SURNAME</th> {{#each (lookup arr 0)}} {{#unless (or (eq @key "user") (eq @key "name") (eq @key "surname"))}} <th>{{@key}}</th> {{/unless}} {{/each}} </tr> {{#each arr}} <tr> <td>{{user}}</td> <td>{{name}}</td> <td>{{surname}}</td> {{#eachDynamic this}} <td>{{value}}</td> {{/eachDynamic}} </tr> {{/each}} </table>
注意:如果需要格式化日期,可在预处理数据阶段直接将日期字符串转换为
DD/MM/YYYY格式,或借助已注册的moment helper处理。
内容的提问来源于stack exchange,提问作者Malco Grosso
相关产品推荐
相关产品推荐

