NodeJS ejs模板的客户端和服务器端呈现

ssm49v7z  于 2023-02-21  发布在  Node.js
关注(0)|答案(4)|浏览(203)

我一直想学习NodeJS能够在服务器端和客户端运行相同的代码。我使用NodeJS与Express和EJS。所以。我有一个.ejs页面与大量的HTML,JS,CSS和一小部分与模板。为了公正,让它像这样:
列表--〉一些.ejs

<ul> 
<% for(i=0;i>the_list.length;i++) { %>
    <li>the_list[i]</li>
<% } %>
</ul>

在服务器上进行一些渲染后,我们有了一个完美的列表。
所以,现在我想在客户端重新渲染它。我做了一些 AJAX 请求,现在我有新的项目在_list中。什么是正确的方法?

jaql4c8m

jaql4c8m1#

根据ejs templates documentation

var template = new EJS({
  text: `
    <ul>
      <% for(i = 0; i < the_list.length; i++) { %>
        <li>the_list[i]</li>
      <% } %>
    </ul>
  `
});
var html = template.render({ the_list: data });
document.getElementById('list-wrapper').innerHTML = html;
cngwdvgl

cngwdvgl2#

<div id="output"></div>
<script src="/assets/js/ejs.js"></script>
<script>
  let blogPosts = [
    {
        title: 'Perk is for real!',
        body: '...',
        author: 'Aaron Larner',
        publishedAt: new Date('2016-03-19'),
        createdAt: new Date('2016-03-19')
    },
    {
        title: 'Development continues...',
        body: '...',
        author: 'Aaron Larner',
        publishedAt: new Date('2016-03-18'),
        createdAt: new Date('2016-03-18')
    },
    {
        title: 'Welcome to Perk!',
        body: '...',
        author: 'Aaron Larner',
        publishedAt: new Date('2016-03-17'),
        createdAt: new Date('2016-03-17')
    }
];
      var html = ejs.render(`<% for(let i = 0; i < posts.length; i++) { %>
    <article>
        <h2><%= posts[i].title %></h1>
        <p><%= posts[i].body %></p>
    </article>
<% } %>`, {posts: blogPosts});
  // Vanilla JS:
  document.getElementById('output').innerHTML = html;
</script>

从最新版本下载ejs.js或ejs.min.js

xeufq47z

xeufq47z3#

当然,EJS可以在客户机上工作,你可以把模板保存在一个字符串变量中,或者把EJS应用到用户提供的输入中,但是更可能的是,你会想把模板存储在一个脚本中(可以是一个外部文件),或者使用fetch从另一个文件中根据需要获取模板。
<script>中使用模板非常简单:

const people = ["geddy", "neil", "alex"];

const template = document
  .querySelector("#template")
  .innerText;

document.querySelector("#output")
  .innerHTML = ejs.render(template, {people});
<!-- could be an external file -->
<script id="template" type="text/template">
<%= people.join(", "); %>
</script>

<div id="output"></div>
<script src="https://unpkg.com/ejs@3.1.8/ejs.min.js"></script>

对于fetch,我将模拟响应,这样它就可以在代码片段中运行:
一个二个一个一个
如果这看起来太重了,你可以把fetch隐藏在一个helper函数中,或者更进一步,为每个URL选择一个属性,然后通过调用一个库函数来插入所有内容,你可以从主代码中抽象出来。

// mock fetch for illustrative purposes; 
// its response content would be in other files
const responses = {
  "/template.ejs": "<%= 42 %>",
  "/other-template.ejs": "<%= 43 %>",
};
fetch = async url => ({text: async () => responses[url]});

[...document.querySelectorAll("[data-template]")]
  .forEach(e => {
    fetch(e.getAttribute("data-template"))
      .then(res => res.text())
      .then(template => {
        e.innerHTML = ejs.render(template);
      });
  });
<script src="https://unpkg.com/ejs@3.1.8/ejs.min.js"></script>
<div data-template="/template.ejs"></div>
<div data-template="/other-template.ejs"></div>

无论哪种方式,请记住,JS将在静态HTML解析和DOM加载之后运行。这意味着数据不会像在服务器上使用EJS那样出现在一个完整的片段中。网络错误是可能的。
如果你想模拟include函数,问题是fetch调用是异步的,而include函数不是。EJS提供了一个include回调,看起来像是提供了一个拉入外部文件的机会。但它是完全同步的,不会等待您返回任何承诺。如何最好地解决这个问题取决于您的用例。

smdncfj3

smdncfj34#

这应该可以工作,看起来你的问题是关系运算符'〉',因为它永远不会输出什么。

<ul>
    <% for(var i=0; i<the_list.length; i++) { %>
        <li>
            <a>
                <%= the_list[i]%>
            </a>
        </li>
    <% } %>
</ul>

相关问题