Express.js查看“全局”
我正在使用Express.js(在Node.js上),我知道你可以通过“locals”参数来显示自定义数据的视图。 ( res.render("template", { locals: { foo: "bar" } });
)
有什么办法可以有“全局”? (即每个视图都可以访问的数据)
我看到view options
,但这不是recursion的,所以如果我用我的模板使用任何本地人,它取代了我设置的本地人。
这是我的用例:我想这样做,以便每个页面可以添加CSS / JS文件,这是我的主要布局的一部分。 问题是,如果我没有明确地在每个渲染上设置这些数组,我得到一个未定义的错误,所以在我的模板中,我总是要做typeof css !== "undefined"
dance。 另外,我还有其他的select框选项列表,我不想明确地添加到每个表单中。
对于Express 3发布后可能遇到这个问题的人来说,值得注意的是,“dynamic助手”方法已经不存在了。
相反,您可以使用app.locals函数,该函数充当可以存储值或函数的对象,然后使其可用于视图。 例如:-
// In your app.js etc. app.locals.title = "My App"; app.locals({ version: 3, somefunction: function() { return "function result"; } }); // Then in your templates (shown here using a jade template) =title =version =somefunction() // Will output My App 3 function result
如果您需要访问请求对象来获取信息,您可以编写一个简单的中间件function并使用app.settingsvariables。
例如,如果您正在使用connect-flash向用户提供消息,则可以这样做:
app.use(function(req, res, next) { app.set('error', req.flash('error')); next(); });
这会让你在模板中访问错误信息= settings.error。
这些主题在这里虽然略作简要介绍: http : //expressjs.com/api.html#app.locals
更新:Express 4
app.locals
现在是一个简单的JavaScript对象,所以每个属性都必须一一设置。
app.locals.version = 3; app.locals.somefunction = function() { return "function result"; }
res.locals
提供了完全相同的function,除了它应该用于请求特定的数据而不是应用程序范围的数据。 用户对象或设置是常见的用例。
res.locals.user = req.isAuthenticated() ? req.user : null; res.locals.userSettings = { backgroundColor: 'fff' }
有一种方法可以使用dynamic视图助手来获得视图的“全局”variables。
从Express.js指南:
app.dynamicHelpers(OBJ)
注册dynamic视图助手。 dynamic视图助手只是接受req,res和在渲染视图之前对服务器实例进行评估的函数。 这个函数的返回值成为它所关联的局部variables。
app.dynamicHelpers({session:function(req,res){return req.session;}});
现在所有的视图都有会话可用,所以会话数据可以通过session.name等来访问:
你可以find一个真正的例子,在这里如何使用它们: https : //github.com/alessioalex/Nodetuts/tree/master/express_samples (节点app.js启动应用程序)
作为作者提到的一个使用视图选项的真实世界的例子:
var app = express.createServer(); app.configure(function() { app.set('views', path.join(__dirname, '..', 'views')); app.set('view engine', 'jade'); app.set('view options', { assetVersion: 1 });
然后在我的layout.jade(在我的情况下的应用程序的基本模板):
link(rel='stylesheet', href='/static/css/' + assetVersion + '/style.css') script(src='/static/js/' + assetVersion + '/script.js')
有了这个小窍门,我只需要更新assetVersion
variables,以确保我的资产不会被caching在Varnish或其他地方。
我结束了对源代码的研究,实际上我发现现在可以在Express的任何版本中使用。 (到目前为止,只能通过GitHub使用)
完成这个最简单的方法是创build一个variables来表示你的视图的默认本地化集合。 然后创build一个函数,接受一个对象,将其与本地合并,并返回合并的对象。
我也通过所有我的本地人在一个容器对象,即{locals:{g:{prop:val}}}
所以在我的意见中,我g.prop
它只会返回null
时,它没有设置,而不是抛出未定义的错误。
function default_page_vars(custom_vars){ var vars = { footer: true, host: req.headers.host.split(':')[0], config: this.config }; if(custom_vars){ for(var k in custom_vars){ vars[k] = custom_vars[k]; } } return { g:vars }; } //within your handler response.render(view, { locals: default_page_vars(other_locals) });
这是一个隐藏的回应,但我终于得到它的工作。
1)这是模块连接闪光灯的一个例子
2)在server.js / app.js中添加一个中间件,将req
添加到locals
。 这允许模板在需要时调用request.flash()
。 如果没有这个, flash()
会在每个请求/redirect中被占用,从而破坏目的。
var app = module.exports = express() , flash=require('connect-flash'); app.configure(function(){ ... app.use(express.session({ secret: "shhh" })); // Start Router app.use(flash()); app.use(function(req, res, next) { res.locals.request = req; next(); }); app.use(app.router); });
3)正常设置你的路线(这是咖啡的脚本,但没有什么特别的)
app.get '/home', (req, res) -> req.flash "info", "this" res.render "#{__dirname}/views/index"
4)当你想要消息时调用request.flash()。 他们消耗在每个电话,所以不要console.log他们或他们会消失:-)
!!! html head title= config.appTitle include partials/_styles body include partials/_scripts #header a(href="/logout") Logout CURRENTUSER h2= config.appTitle #messages - var flash = request.flash() each flashType in ['info','warn','error'] if flash[flashType] p.flash(class=flashType) = flash[flashType] block content h1 content here