与EJS斗争和不是所谓“本地”变数的范围
我想知道如何使用EJS模板来编写我的node.js应用程序。 实际上,我正在寻找一种合适的方法来在局部/模板中使用默认值来定义局部variables。
我现在很快就会发现它的作用:
当我打电话给一个模板,像这样:
<%- partial(__view.partialPath('tagPopover'), { title_popover: sentence.nickname, content_tag: '#' + sentence.nickname, icon_popover: 'http://placehold.it/64x64' }) %>
我用_tagPopover.ejs
部分pipe理默认值:
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将交互variablesvar title_popover
并创build一个局部variables, 然后读取variablestitle_popover
的实际值。 所以我最终会得到一个null
,即使我实际上发送了一个参数…
当我发现这一点时,我决定不使用var
关键字…但是最近我发现我用这种方式创build的所有variables实际上都是global
! 这意味着这是一个非常糟糕的解决scheme,因为我可能最终通过加载视图重写全局variables!
我相信这将是一个后来的斗争,我不希望我的意见默认设置/重置全局variables(谁会?!)
你有这个解决scheme吗? 我已经想过几个,但我不喜欢任何:
- 使用
var
关键字,但也使用本地variables的before模式 ,以避免重置参数:var l_title_popover = typeof title_popover != 'undefined' ? title_popover : ''
var l_title_popover = typeof title_popover != 'undefined' ? title_popover : ''
。 这看起来很糟糕,令人困惑。 - 使用像
view.title_popover = typeof title_popover != 'undefined' ? title_popover : ''
的命名空间view.title_popover = typeof title_popover != 'undefined' ? title_popover : ''
view.title_popover = typeof title_popover != 'undefined' ? title_popover : ''
。 我希望我的variables是本地的,而不是全局的,如果我这样做,我会有全局的东西,一直存在于内存中。
你将如何处理? 我很好奇,也许有一些EJS的方式来处理这个或一个帮手,我不知道。
ejs中有一个filter的概念。 另请参阅添加filter 。
基本上我认为你正在寻找类似的东西..下面的代码将设置title_popover如果存在res.locals,否则它设置为“一些默认值”
<%=: locals | get:'title_popover','some default value' %> ejs.filters.get = function(obj, prop, default) { return obj[prop] === undefined ? default : obj[prop]; };
我相信这是在ejs中最简单的方法,但也可能有其他一些方法。 看起来像这实际上正在讨论的github票 🙂
编辑 – 这个博客文章似乎给一些替代品使用下划线库。 看起来他们是以某种方式在布局中包装模板(我没有完全熟悉文章,但它似乎是有意义的表面)。
我只用了上面的方法。
EJS不是一个好的模板,因为它是非常古老和不活跃的。 也就是说,JS的模板引擎在variables传递方面并不是那么完美。 我正在使用Sails框架,我所做的只是将variables传递给我的路由设置(如果它们是硬编码的),或者在我的控制器,如果它们是dynamic的。
也可以通过策略为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(); };
Sailsbuild立在Express上,所以这些信息可能会有用。 但请注意,风帆策略适用于控制器操作,这意味着如果您定义了一个简单的path进行查看,它将不适用 – 您必须将其路由到特定的控制器。 但是,您可以将这个对象放到它们自己的路线中:
//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提供了一个相对简单的解决scheme,也相对简单。
如果你喜欢使用纯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);
顺便说一句,filter在第二版中从EJS中移除。 他们是一个非标准的function,与embedded式JavaScript无关,而且很容易使用自己的代码进行复制。
我在ejs中定义了默认variables,如下所示:
<% var username, password%> <script> var username = "<%= username %>",password = "<%= password %>" %> </script>