[英]Render Handlebars template with variable length dictionaries
我一直没有使用 Handlebars 和 Javascript,但我已经能够拼凑出一个主要工作的应用程序。 但是,在尝试添加更多数据后,我遇到了麻烦。
我有一个 Handlebars 模板,它从一个数组中呈现多个字典,以显示多个 API 调用的结果。 根据我阅读的另一篇 Stack Overflow 文章,我能够编写一个辅助函数,该函数将数组分解为其组件字典,并根据从字典中获取 key:values 来呈现它们。
到目前为止,这一直运行良好,因为作为每个 API 调用产品的字典长度相同。 我想以抄送电子邮件的形式向它们添加一些数据,但并非所有对象都具有相同数量的抄送电子邮件。
是否可以使用不同数量的键:值动态呈现模板?
这是我构建数组的位置(这是在 API 调用之后,我获取其他所需值并初始化最终数组。我还在前一个函数中获取了 linksTicketCcs 数组并将其传入。):
let requesterName = data['user']['name'];
let requesterEmail = data['user']['email'];
let dataDictionary = {'ticket_number': ticketId, 'name': requesterName, 'email': requesterEmail, 'subject': ticketSubject,
'status': ticketStatus, 'description': ticketDescription};
for (let i = 0; i < linkedTicketCcs.length; i++) {
dataDictionary[`linked_cc_${i}`] = linkedTicketCcs[i]
}
finalArray.push(dataDictionary);
此函数在另一个函数的 for 循环中运行,因此会构建多个字典,然后将其推送到最终数组。 数组中的每个字典现在都有正确数量的抄送电子邮件。
然后使用此辅助函数将最终数组分解为其组件
Handlebars.registerHelper("each", function (options) {
let ret = "";
for (let i = 0; i < finalArray.length; i++) {
ret = ret + options.fn(finalArray[i]);
}
return ret;
});
然后将数据注入以下模板:
{{#each}}
<table>
<tr>
<td><strong>Ticket: </strong> <a href="#" data-toggle="tooltip" data-trigger="hover focus" data-placement="top" title="View ticket" onclick="openTicket('{{ticket_number}}')">{{ticket_number}}</a> <strong>Status: </strong>{{status}}</td>
</tr>
<tr>
<td><strong>Subject: </strong>{{subject}}</td>
</tr>
<tr>
<td><strong>Requester: </strong><a href="mailto:{{email}}" class="no-link email">{{email}}</a></td>
</tr>
</table>
{{/each}}
作为一种解决方法,我可以渲染这样的东西来添加抄送的电子邮件:
{{#if linked_cc_0}}
<tr>
<td><strong>CC: </strong><a href="mailto:{{linked_cc_0}}" class="no-link email">{{linked_cc_0}}</a></td>
</tr>
{{/if}}
{{#if linked_cc_1}}
<tr>
<td><strong>CC: </strong><a href="mailto:{{linked_cc_1}}" class="no-link email">{{linked_cc_1}}</a></td>
</tr>
{{/if}}
{{#if linked_cc_2}}
如果 key:value 存在于传递给模板的数据中,则有条件地呈现每个链接的 CC。 然而,似乎应该有一种更简洁的方法来做到这一点,也许使用另一个辅助函数。
所以我需要能够做的是在一个数组中呈现来自字典的多个模板块,其中字典的长度并不总是相同。 我认为这可以做到,但我不确定如何做到。
使用#each
内置,你应该能够得到你想要的:
{{#eachArray}}
<table>
<tr>
<td><strong>Ticket: </strong>
<a href="#" data-toggle="tooltip"
data-trigger="hover focus"
data-placement="top" title="View ticket"
onclick="openTicket('{{ticket_number}}')">{{ticket_number}}
</a> <strong>Status: </strong>{{status}}
</td>
</tr>
<tr>
<td><strong>Subject: </strong>{{subject}}</td>
</tr>
<tr>
<td><strong>Requester: </strong><a href="mailto:{{email}}" class="no-link email">{{email}}</a></td>
</tr>
{{#each ccList}}
<tr>
<td><strong>CC: </strong><a href="mailto:{{this}}" class="no-link email">{{this}}</a></td>
</tr>
{{/each}}
</table>
{{/eachArray}}
您选择的数据结构使您的问题变得困难。
通过使每个抄送电子邮件成为电子邮件对象( linked_cc_0
、 linked_cc_1
等)上的唯一键,您将迫使模板必须知道所有这些键才能呈现值。 这不是理想的结构。
既然您的抄送电子邮件是一个任意长的字符串列表,为什么不这样构建您的数据呢?
例如,如果每个电子邮件对象都有一个linked_ccs
键,该键的数组值包含 0 个或多个字符串,那么在模板中使用简单的#each
很容易处理。
你只需要指定linkedTicketCss
的dataDictionary
的对象linked_css
键,如:
dataDictionary.linked_ccs = linkedTicketCcs;
您的模板将变为:
{{#each emails}}
{{! existing email template here }}
{{#each linked_ccs as |linked_cc|}}
<tr>
<td><strong>CC: </strong><a href="mailto:{{linked_cc}}" class="no-link email">{{linked_cc}}</a></td>
</tr>
{{/each}}
{{/each}
我已经创建了一个小提琴供您参考。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.