14

私が欲しいのは次のようなものです:

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);
});

index.ejs :

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

        <% makeList(listData1) %>

        <p>lorem ipsum</p>

        <% makeList(listData1) %>
    </body>
</html>

???


結果:

<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>

質問: ??? には何が入りますか? セクションおよび/または上記で変更する必要がありますか?


これまでに試したこと

試行 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>

makeList.ejs

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

<% makeList = function(data){ %>
    <% if(data){ %>
        <ul>
            <% data.map(makeListItem) %>
        </ul>
    <% } %>
<% } %>

この状況では、makeListItemとの両方makeListが呼び出されていますが、スコーピングまたはその他の理由により、それらが呼び出されるようになったときに、実際にテンプレートに出力できないように見えます。


試行 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>

makeList.ejs

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

<% if(data){ %>
    <ul>
        <% data.map(makeListItem) %>
    </ul>
<% } %>

試行 3

-これには基本的にejs-localsをいじる必要がありましたが、機能がやや不足していることがわかりました。

アプリケーションに別の npm モジュールを含める場合は、それをより完全なソリューションにしたいのですが、それでも理想的な世界では、なくして自分で書きたいと思います。


この投稿の長さをお詫びします。すぐに手に負えなくなりました。ここまでできたら褒めてあげてください。

任意の入力をいただければ幸いです。

4

2 に答える 2

31

これはどう:

// 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>
于 2013-04-15T06:40:49.413 に答える
0

(少なくとも最初の例では) 私が思いつく唯一のことは、ejsVariables から listData1 を削除する makeList() 関数です。その例の makeList() を見せてもらえますか?

試行 1 では、パラメーターなしで makeList() を呼び出しています。

于 2013-04-15T05:30:17.800 に答える