ejs中的函数

Jos*_*hua 10 javascript ejs node.js

我想拥有的是这样的:

app.js(节点进程,包括等为简洁而排除但使用ejs作为渲染引擎):

app.get('/', function(req, res){

    var ejsVariables = {
        title : 'ideal ejs function example',
        listData1 : {
            listTitle : 'my list',
            listItems : [
                { name : 'first item', class : 'foo' },
                { name : 'second item', class : 'bar' },
                { name : 'last item', class : 'foo' }                ]
        },
        listData2 : {
            listTitle : 'your list',
            listItems : [
                { name : 'a widget', class : 'foo' },
                { name : 'another widget', class : 'baz' }
            ]
        }
    };

    res.render('index', ejsVariables);
});
Run Code Online (Sandbox Code Playgroud)

index.ejs:

<html>
    <head>
        <title><%= title %></title>
    </head>
    <body>
        <h1><%= title %></h1>

        <% makeList(listData1) %>

        <p>lorem ipsum</p>

        <% makeList(listData1) %>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

???


结果:

<html>
    <head>
        <title>ideal ejs function example</title>
    </head>
    <body>
        <h1>ideal ejs function example</h1>

        <ul>
            <li class="foo">first item</li>
            <li class="bar">second item</li>
            <li class="foo">another item</li>
        </ul>

        <p>lorem ipsum</p>

        <ul>
            <li class="foo">a widget</li>
            <li class="baz">another widget</li>
        </ul>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

问题:怎么回事?部分和/或应该在上面改变?


到目前为止我尝试过的

尝试1

- 我真的希望这个工作,但事实并非如此

index.ejs

<html>
    <head>
        <title><%= title %></title>
    </head>
    <body>
        <h1><%= title %></h1>
        <% var makeList; %>
        <!-- this variable is declared here as those declared within the include are not
        accessible from the file from which it is called, I'm guessing some sort of 
        function scope is coming into play here -->

        <% include makeList %>

        <% makeList(listData1) %>

        <p>lorem ipsum</p>

        <% makeList(ListData2) %>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

makeList.ejs

<% function makeListItem(itemData){ %>
        <li class="<%= itemData.class %>" ><%= itemData.name %></li>
<% } %>

<% makeList = function(data){ %>
    <% if(data){ %>
        <ul>
            <% data.map(makeListItem) %>
        </ul>
    <% } %>
<% } %>
Run Code Online (Sandbox Code Playgroud)

在这种情况下都makeListItemmakeList被调用,它只是似乎是由于作用域或别的东西,当他们来到被称为他们无法实际输出的模板.


尝试2

- 这实际上有效,我只是不喜欢我最终使用包含而不是某种函数调用的方式.

index.ejs

<html>
    <head>
        <title><%= title %></title>
    </head>
    <body>
        <h1><%= title %></h1>

        <% var data = listData1 %>
        <% include makeList %>

        <p>lorem ipsum</p>

        <% var data = listData2 %>
        <% include makeList %>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

makeList.ejs

<% function makeListItem(itemData){ %>
        <li class="<%= itemData.class %>" ><%= itemData.name %></li>
<% } %>

<% if(data){ %>
    <ul>
        <% data.map(makeListItem) %>
    </ul>
<% } %>
Run Code Online (Sandbox Code Playgroud)

尝试3

- 这基本上涉及到与ejs-locals的混乱,但我发现功能有点缺乏.

如果我要在我的应用程序中包含另一个npm模块,我真的希望它是一个更完整的解决方案,但即便如此,在一个理想的世界中我宁愿不用自己编写它.


对于这篇文章的篇幅感到抱歉,它很快失控了.如果你已经走到这一步,我推荐你.

任何投入将不胜感激.

rob*_*lep 24

这个怎么样:

// app.js
var ejs = require('ejs');
var fs  = require('fs');

app.locals({
  makeList  : function(list) {
    var template = fs.readFileSync('makeList.ejs', 'utf-8');
    return ejs.render(template, list);
  }
});

// index.ejs
<%- makeList(listData1) %>
  ^ important!

// makeList.ejs
<ul>
  <% listItems.forEach(function(item) { %>
    <li class="<%= item.class %>"><%= item.name %></li>
  <% }); %>
</ul>
Run Code Online (Sandbox Code Playgroud)