我对Web应用程序有相当标准的要求,其中大多数页面将使用单个布局进行呈现(我使用的是把手,但同样适用于Jade或其他任何东西)。我应该如何在express.js页面布局中填充数据
布局使用数据库中相当多的数据,可能需要多次查找。我应该如何构造代码,以便不必在每个控制器中为每个页面/路径检索布局使用的数据?在许多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()
呼叫控制器,并为他们是添加剂等等多于一个可以适用于某一组控制器。
有没有一个模块可以帮助你做到这一点,或者只是一个通用的“最佳实践”方式来实现它?
是的,您对数据使用的理解是正确的,像这样的解决方案也可以缓存我也需要的布局数据。但是,如何改变中间件的使用涉及到更改潜在的许多控制器和路由的声明,这似乎很不雅观。例如,这种中间件可以按照约定或模式匹配来应用,而不是在每个控制器中重复它? – darrend
如果您在定义任何路由之前定义了该中间件,那么它将自动注入到每个路由中,并且如果将'req.layoutData = dataFromDb;'更改为'res.locals.layoutData = dataFromDb;',那么您不需要更改任何内容你的控制器layoutData将在每个模板上都可用。现在对于模式匹配,如果你不需要加载layoutData,你可以排除一些路由。我举了一个例子来看更新的答案。 –
好的,是的,它更好,但拦截器(中间件)知道控制器以便排除它们有点落后。我起初有点惊讶,我以为我错过了一些express的一流功能,因为我用在其他语言中的每个web框架都具有这种性质。我想sailsjs.org是为快速应用程序提供这种更高级别的功能的集合..似乎更多的是我从扫视后看到的。 – darrend