[英]How should I populate data in an express.js page layout
对于Web应用程序,我有一个相当标准的要求,其中大多数页面将以单一布局呈现(我使用的是把手,但同样适用于Jade或其他任何东西)。
该布局使用了来自数据库的大量数据,并且可能需要多次查找。 我应该如何构造代码,以便不必在每个页面/路由的每个控制器中检索布局使用的数据? 在许多Web框架中,有一种简单的方法可以按模式拦截路由,并让拦截器进行所需的查找,从而修饰由它们包装的控制器生成的模型。
感觉应该有某种方法可以对中间件进行正确的定义,但是我无法弄清楚。
寻找可以执行以下伪代码显示的内容:
router.get('/', ctrlPublic.index);
router.get('/index.html', ctrlPublic.index);
router.get('/find-us.html', ctrlPublic.findUs);
// apply same interceptor to all (/*)
router.intercept('/*', ctrlDecorator.main);
// ctrlPublic...
index: function(req, res) {
// get data for index page, then render index.hbs
},
findUs: function(req, res) {
// get data for find-us page, then render find-us.hbs
}
// ctrlDecorator...
main: function(req, res) {
// lookup data needed by main layout - this gets automatically
// added to the model used by the page ctrlPublic handlers
}
理想情况下,我希望拦截器通过模式匹配而不是在router.get()
调用中声明来将控制器作为目标,并使它们具有可加性,以便多个控制器可以应用于一组特定的控制器。
是否有某个模块可以帮助实现这一目标,或者只是实现该目标的一般“最佳实践”方式?
如果我正确理解您的问题,则需要全局中间件来获取数据并将其传递给相应的控制器,这样您就不会在控制器上加载相同的布局数据了吗?
在这种情况下,请创建一个全局中间件
app.use(function(req, res, next){
var excludeMiddleware = ['login', 'test', 'test2'];
//simple example for bypassing the middleware
for(var i = 0; i < excludeMiddleware.length; i++){
if(excludeMiddleware[i] === req.path) { return next(); }
}
someAsyncFnFromDb.then(function(dataFromDb){
//req.layoutData = dataFromDb;
res.locals.layoutData = dataFromDb;
return next();
}).catch(function(err){
return next(); // or throw new Error(err)
});
});
如果使用req.layoutData
,则在控制器中将数据分配给render函数,例如
res.render('myView', { layoutData: req.layoutData });
或者如果您使用res.locals.layoutData
,则控制器res.locals.layoutData
,并且layoutData将在您的视图上可用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.