[英]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.