[英]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.