EJS是否能够处理array.map(callback)?

7

我将一个对象数组传递给EJS模板,我希望使用数组的常规.map()方法将其映射为链接。但是出于某些原因,我无法在EJS中按照预期工作的回调函数传递给map(),并且我得到了空结果。

我的数据是一个对象数组,每个对象都有一个“section”和一个“name”键。这个数组被作为“entries”传递给模板:

siteHeaders = [ { section: "home", name: "Home"}, 
                { section: "about", name: "About Me"}, 
                ... plus few more ]

模板长这样,我已经存到了本地变量中(惊喜),叫做template:
<% entries = entries.map(function(elem) { -%>
  <% return -%>
  <a href="/<%= elem.section %>">
    <%= elem.name %>
  </a>
<% } ) -%>
<p><%- entries.join(" | ") %></p>

当我调用require('ejs').render(template, {entries: siteHeaders})时,这个模板的结果如下:
          <p> |  |  |  | </p>

我不明白的是为什么这个在REPL中正常工作的映射调用,在EJS模板中却无法正常工作:

> siteHeaders.map(function(e){ return '<a href="/' + e.section +'">' + e.name + '</a>' })
[ '<a href="/home">Home</a>',
  '<a href="/guide">About Me</a>',
  '<a href="/quickstart">Portfolio</a>',
  '<a href="/reference">Blog</a>',
  '<a href="/downloads">Contact</a>' ]
>

有线索吗?

我只是好奇为什么你想使用map而不是entries.forEach(),并直接输出你的HTML。 - chovy
没有特别的原因,只是我认为使用join()函数在每个条目之间放置管道符号表达这个想法更加清晰。请参考下面Vadim Baryshev的答案。 - Jason Black
3个回答

7
这段代码应该可以正常工作:
<% entries = entries.map(function(elem) {
    return '<a href="/' + elem.section + '">' + elem.name + '</a>';
}) -%>
<p><%- entries.join(" | ") %></p>

在函数内部无法使用简单的HTML,只能在循环和条件语句中使用。


糟糕。是的,我考虑过你的解决方案,但从哲学上讲,那又回到了手动连接字符串以构建HTML的旧世界,而模板系统应该使我们摆脱这种情况。这让我感到不爽,所以我想尝试一下更像Node的风格。谢谢你的提示! - Jason Black

3

虽然不如join(' | ')这么简洁,但如果您不想进行连接操作,可以采用以下方法:

<% entries.forEach(function(entry, i, entries){ %>
    <a href="<%= entry.section %>"><%= entry.name %></a>
    <%= i == entries.length-1 ? ' | ' : '' %>
<% } %>

2

我无法在EJS中使用map,但是我找到了一种对我来说至少很容易的方法。

<ul>
  <% for (item of toDoList) { %>
    <li> <%= item %> </li>
  <% } %>
</ul>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接