我需要在一些EJS代码中使用Javascript变量(在前端定义),如下所示:
var selected = 1;
<% for (var i=0; i < supplies.length; i++) { %>
if (i == selected) {
console.log(supplies);
}
<% } %>
我使用的是EJS、Express.js和socket.io。我可以通过向我的Node.js服务器实例发送一条消息来将Javascript变量转换为EJS变量,但这有点傻……有没有办法在EJS中使用Javascript变量?
编辑:在用户从下拉菜单中选择一项后,我想访问supplies,这是一个javascript数组。当他选择此项时,使用上述代码的javascript函数需要访问一些EJS。这就是为什么我需要在EJS中使用普通的Javascript变量。
发布于 2012-05-28 07:56:17
是否可以将JavaScript变量传递到模板中?
可以将更多数据放入模板并重新呈现,但不是以您所想的方式,也不需要向服务器发出另一个请求(除非是为了获取更多数据,而不是为了获取更多HTML)。
解决方案:
如果没有更多的细节,这个问题将很难回答,所以我将做出一些假设,说明为什么要将选定的值传递到EJS模板中。我会尽我最大的努力用有限的信息来回答你的目标。
看起来您的用户正在页面上执行一些操作,比如选择清洁用品,而您希望根据用户选择的元素以不同的方式呈现数据。为此,您可以重新呈现模板并传递标识所选元素的数据,使用视图帮助器将特定类应用于所选元素:
以下是修改后的cleaning.ejs模板,其中包含使用视图助手添加的类:
cleaning.ejs:
<script>
// NOTE: even if uncommented, JavaScript inside a template will not run.
// var selected = 1;
</script>
<h1><%= title %></h1>
<ul>
<% for(var i=0; i<supplies.length; i++) { %>
<li>
<!-- apply a class to the selected element -->
<a class='<%= supplies[i].selected %>' href='supplies/<%= supplies[i].value %>'>
<%= supplies[i].value %>
</a>
</li>
<% } %>
</ul>
呈现的HTML如下所示:
<script>
/** NOTE: Script blocks will not fire in rendered templates. They are ignored
// var selected = 1;
</script>
<h1>Cleaning Supplies</h1>
<ul>
<li>
<a class="" href="supplies/Broom">
Broom
</a>
</li>
<li>
<!-- Note the selected element -->
<a class="selected" href="supplies/mop">
mop
</a>
</li>
<li>
<a class="" href="supplies/Hammer">
Hammer
</a>
</li>
</ul>
此视图是使用以下JavaScript代码呈现的:
// modified data structure so that array of supplies contains objects
// with the name of the item and whether or not it's selected.
data = {
"title":"Cleaning Supplies",
"supplies":[
{
"value":"Broom",
"selected":""
},
{
"value":"mop",
"selected":"selected"
},
{
"value":"Hammer",
"selected":""
}
]
};
// pass data into template and render
var html = new EJS({url: 'cleaning.ejs'}).render(data);
// add HTML to the DOM using a <div id="container"></div> wrapper.
document.getElementById("container").innerHTML = html;
如您所见,suppliesi.selected将选定的类应用于在数据结构中标记为选中的元素。我修改了href值,以便它访问第i个数组项中的对象,而不是数组本身的值。
现在,当选定的项被修改时,我们只需修改data变量,重新呈现EJS模板,并将其添加到DOM中。
在HTML文档头显示此CSS后,您将看到类似于下面显示的内容:
<style>
.selected { color:red; }
</style>
为什么模板中的JavaScript不能运行:
您试图用来操作JavaScript值或在EJS模板中使用JavaScript值的方法将不起作用。这主要与JavaScript何时执行的上下文有关。
您认为EJS模板是在客户端编译的,这一点是正确的。但是,视图帮助器中的JavaScript独立于全局上下文中的JavaScript执行。从ejs.js源代码来看,似乎在这个过程中使用了eval。
此外,EJS将呈现的超文本标记语言作为字符串返回,EJS的文档指导我们使用innerHTML将呈现的模板字符串注入DOM:
document.getElementById("container").innerHTML = html;
无论您使用哪种视图技术,当涉及到JavaScript时,一些浏览器的一个基本事实是:某些浏览器可能不会评估使用innerHTML添加到DOM中的 view 块。
换句话说,在我的测试模板中,当我尝试添加脚本标记以将所选值输出到控制台时,我可以看到脚本块已经添加,但由于innerHTML的工作方式,它没有被执行:
示例模板演示了如果使用innerHTML:添加JavaScript将不会运行
<h1><%= title %></h1>
<ul>
<% for(var i=0; i<supplies.length; i++) { %>
<span id="selected"></span><script>console.info('test <%= i %> = <%= supplies[i] %>');</script>
<li>
<a href='supplies/<%= supplies[i] %>'>
<%= supplies[i] %>
</a>
</li>
<% } %>
</ul>
呈现的HTML语言:
如下所示,console.log语句存在于HTML语言中。但是,当使用innerHTML添加时,它们将不会触发。
使用技术的方法是限制它们的使用,渲染视图。将你的逻辑保持在“常规JavaScript”中。
<h1>Cleaning Supplies</h1>
<ul>
<span id="selected"></span><script>console.info('test 0 = Brrom');</script>
<li>
<a href='supplies/Brrom'>
Brrom
</a>
</li>
<span id="selected"></span><script>console.info('test 1 = mop');</script>
<li>
<a href='supplies/mop'>
mop
</a>
</li>
<span id="selected"></span><script>console.info('test 2 = Hammer');</script>
<li>
<a href='supplies/Hammer'>
Hammer
</a>
</li>
</ul>
可以在Google Code Embedded JavaScript站点上的EJS模板上找到更多示例和文档。
https://stackoverflow.com/questions/10777246
复制相似问题