与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吗? 我已经想过几个,但我不喜欢任何:

  1. 使用var关键字,但也使用本地variables的before模式 ,以避免重置参数: var l_title_popover = typeof title_popover != 'undefined' ? title_popover : '' var l_title_popover = typeof title_popover != 'undefined' ? title_popover : '' 。 这看起来很糟糕,令人困惑。
  2. 使用像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>