我想知道如何使用EJS模板编写我的node.js应用程序。 我实际上正在寻找一种在部分/模板中使用默认值定义局部变量的正确方法。
我很快就会发现它现在有效:
当我调用模板时,像这样:
<%- partial(__view.partialPath('tagPopover'), {
title_popover: sentence.nickname,
content_tag: '#' + sentence.nickname,
icon_popover: 'http://placehold.it/64x64'
}) %>
我在_tagPopover.ejs
partial:
title_popover = typeof title_popover != 'undefined' ? title_popover : ''
classes_tag = typeof classes_tag != 'undefined' ? classes_tag : 'tags'
icon_popover = typeof icon_popover != 'undefined' ? icon_popover : false
content_tag = typeof content_tag != 'undefined' ? content_tag : ''
我不使用var
关键字,因为它根本不起作用,例如,如果我这样做:
var title_popover = typeof title_popover != 'undefined' ? title_popover : ''
然后EJS会插入var title_popover
并创建一个局部变量,然后再读取变量title_popover
的实际值。因此,即使我实际发送了一个参数,我也会得到一个null
当我发现这一点时,我决定不使用var
关键字...但我最近发现,我用这种方式创建的所有变量实际上都是global
!这意味着它是一个非常糟糕的解决方案,因为我可能最终通过加载视图来重写全局变量!
我相信这将是一个艰难的过程,我不希望我的观点默认设置/重置全局变量(谁会?!)
你有什么解决方案吗?我已经考虑了几个,但我不喜欢任何:
var
关键字,但也可以使用模式 之前的局部变量来避免重置参数:var l_title_popover = typeof title_popover != 'undefined' ? title_popover : ''
。这看起来很糟糕,令人困惑。view.title_popover = typeof title_popover != 'undefined' ? title_popover : ''
之类的命名空间。我希望我的变量是本地变量,而不是全局变量,如果我这样做,我将会有一些全局存在于内存中的东西。你会怎么处理?我很好奇,也许有一些EJS方式来处理它或帮助,我不知道。
答案 0 :(得分:2)
ejs中有filters的概念。另请参阅adding-filters。
基本上我认为你正在寻找类似的东西。如果存在于res.locals中,下面的代码将设置title_popover,否则它设置为'某个默认值'
<%=: locals | get:'title_popover','some default value' %>
ejs.filters.get = function(obj, prop, default) {
return obj[prop] === undefined ? default : obj[prop];
};
我相信这是在ejs中最简单的方法,但可能还有其他一些方法。看起来像this actually being discussed on a github ticket:)
编辑 - This blog post似乎使用下划线库提供了一些替代方案。看起来他们正在以某种方式将模板包装在一个布局中(我还没有完全理解这篇文章,但它似乎在表面上有意义。)
然而,我只使用了上述方式。
答案 1 :(得分:0)
EJS不是一个好的模板,因为它很老而且不活跃。也就是说,JS的模板引擎在传递变量方面并不是那么精彩。我正在使用Sails框架,我所做的只是将变量传递给我的路由设置中的视图(如果它们是硬编码的)或者在我的控制器中,如果它们是动态的。
还可以通过政策向res.locals
提供标准路线设置。
例如,我的风帆路线中有以下设置:
'GET /':{
controller: 'IndexController.js',
action: 'displayIndexPage',
title: 'Main page',
},
'GET /flowchart': {
controller: 'FlowchartController.js',
action: 'displayFlowchart',
title: 'Flowchart'
}, //...
然后我的政策viewToLocals.js
包含以下代码:
module.exports = function(req, res, next) {
res.locals.view = req.options.title;
return next();
};
这个,顺便说一句,不会覆盖我从控制器或任何其他文件传递给视图的任何数据。如果我遇到你的问题,我能做的就是这样:
//setPageParamsPolicy.js
module.exports = function(req, res, next) {
res.locals.popovers = {
title: ('undefined') ? res.get('body').username : 'Default title', //or wherever you fetch data from
icon : ('undefined') ? res.get('body').avatar : 'www.site.com/defaultAvatar.jpg'
}
return next();
};
Sails是基于Express构建的,所以这些信息可能会有用。但是请注意,sails策略适用于控制器操作,这意味着如果您定义一个简单的路径来查看,它就不会应用 - 您必须将其路由到特定的控制器。但是,您可以将此对象放入其中的路径:
//routes.js
'GET /userpanel': {
view: 'userpanel',
locals = {
popover: {
title: ('undefined') ? res.get('body').username : 'Default title', //or wherever you fetch data from
icon : ('undefined') ? res.get('body').avatar : 'www.site.com/defaultAvatar.jpg'
}
}
}
我也对此感到疑惑,并得出结论,没有简单的方法可以做到这一点。但对我来说,Sails提供了一个相对简单的解决方案,也是相对简单的。
答案 2 :(得分:0)
如果你喜欢使用普通的JS,那么EJS是一种出色的模板语言。该项目目前非常活跃。
NPM上的EJS模块(现在为v2)在此处主动维护:https://github.com/mde/ejs。 (旧的v1仓库不再维护。)
着陆网站位于:http://ejs.co
不应在模板中设置数据的默认值。模板只应用于渲染。更好的方法是在传递数据之前预处理数据:
var defaultVals = {
foo: 'FOO',
bar: 'BAR'
};
// Mix in left to right: https://gist.github.com/mde/81b131ff6810ed7c4e0e
var dataObj = mixin({}, defaultVals, {bar: 'NOT BAR'});
// Outputs "FOO, NOT BAR"
ejs.render('<%= [foo, bar].join(", "); %>', dataObj);
顺便提一下,在v2中从EJS中删除了过滤器。它们是一个非标准的功能,与嵌入式JavaScript无关,并且易于使用您自己的代码进行复制。
答案 3 :(得分:0)
我在ejs中定义了这样的默认变量:
<% var username, password%>
<script>
var username = "<%= username %>",password = "<%= password %>" %>
</script>