繁体   English   中英

ejs模板的客户端和服务器端渲染

[英]Client side and Server side rendering of ejs template

我一直想学习 NodeJS 以便能够在服务器端和客户端运行相同的代码。 我将 NodeJS 与 Express 和 EJS 一起使用。 所以。 我有一个 .ejs 页面,其中包含大量 HTML、JS、CSS 和少量模板。 为了正义,让它变成这样:

the_list-->some.ejs

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

在服务器上进行一些渲染后,我们有一个完美的列表。

所以。 现在我想在客户端重新渲染它。 我提出了一些 ajax 请求,现在我在 the_list 中有新项目。 什么是正确的方法?

根据 ejs 模板文档

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

当然,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.6/ejs.min.js"></script>

对于fetch ,我将模拟响应,以便它可以在片段中运行:

 // mock fetch for illustrative purposes; // its response content would be another file fetch = async url => ({text: async () => '<%= people.join(", "); %>'}); fetch("/your-template") .then(res => res.text()) .then(template => { const people = ["geddy", "neil", "alex"]; document.querySelector("#output").innerHTML = ejs.render(template, {people}); });
 <script src="https://unpkg.com/ejs@3.1.6/ejs.min.js"></script> <div id="output"></div>

如果这看起来繁重,您可以将fetch在辅助函数中,或者更进一步,为每个 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.6/ejs.min.js"></script> <div data-template="/template.ejs"></div> <div data-template="/other-template.ejs"></div>

无论哪种方式,请记住 JS 将在解析静态 HTML 并加载 DOM 之后运行。 这意味着数据不会像在服务器上使用 EJS 时那样全部出现在一个完整的片段中。 网络错误是可能的。

另请参阅使用来自 express 客户端的 ejs partials 如果你想模拟include函数,问题是fetch调用是异步的,但include函数不是。 EJS 提供了一个包含回调,看起来它提供了一个拉入外部文件的机会,但它纯粹是同步的,不会等待您返回的任何承诺。 如何最好地解决这个问题取决于您的用例。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM