将动态内容集成到Sails.JS应用程序中的layout.ejs文件的正确方法是什么?

10 sails.js

说我在Sails.js中写了一个博客应用程序.

每一页在此应用程序,有一个侧边栏部件被称为"最近的帖子",它列出了5最近发表的文章的标题和点击它们将带您到相关的帖子.

因为这个侧边栏小部件出现在每个页面上,所以它应该在layout.ejs.但是,这里我们有一个冲突 - 动态内容只应该在控制器动作中从数据库中提取以呈现特定视图.

动态内容不适用于特定视图,而是适用于整个站点(通过layout.ejs).

通过我理解的约定,我必须在呈现视图的每个控制器操作中获取侧边栏小部件的动态内容数据(否则当我尝试在layout.ejs文件中调用本地时,我会得到未定义的错误).

我尝试/考虑过的事情:

  • 呈现视图的每个控制器操作中加载该动态内容(此解决方案非常糟糕)并在layout.ejs中调用该动态内容,就好像它是特定视图的本地内容一样.这工作正常,但违反DRY原则,坦率地说,在每个控制器操作中必须对数据库运行相同的查询是一件痛苦的事.

  • 根据另一个类似的stackoverflow问题,创建一个新配置(EG config/globals.js),将我的数据库中的动态内容作为变量加载到该配置文件中,然后调用sails.config.globals.[variable_name]我的layout.ejs文件.这也很有用,因为显然配置变量可以在应用程序的任何地方使用 - 但它是一个hacky解决方案,我不是它的粉丝(我加载的内容只是5个最近帖子的标题和slug,而不是"全局配置选项",正如解决方案所暗示的那样).

  • 运行查询以在某些<% %>标记之间直接获取.EJS文件中的动态内容.我不确定这是否会起作用,但即使它确实如此,也违背了关注点的分离MVC原则,我想尽可能避免这样做(如果它甚至可行).

  • 根据冗长的IRC讨论@ http://webchat.freenode.net/?channels=sailsjs,建议创建策略并将该策略映射到我的所有控制器.在该策略中,查询数据库中最近的5个帖子,并将它们设置为req.recentposts.这个解决方案的问题在于,虽然最近的帖子数据将传递给每个控制器,但我仍然必须将req.recentposts数据传递给我的视图 - 这样我仍然需要修改每个res.view({在每一个动作中.我不必在每个操作中都有数据库查询,这很好,但我仍然需要为每个呈现视图的操作添加一行代码...这不是DRY而我正在寻找一个更好的解决

那么,什么是正确的解决方案,而不需要在每个控制器动作中加载动态内容(一个坚持DRY的解决方案是我正在寻找的),以获得一些动态内容可用于我的layout.ejs文件?

Paw*_*oła 5

在文件夹/ config中,您应该创建一个文件express.js并添加类似的东西:

module.exports.express = {
    customMiddleware: function(app){
        app.use(function(req, res, next){
            // or whatever query you need
            Posts.find().limit(5).exec(function(err, posts){
                res.locals.recentPosts = posts;
                // remember about next()
                next();
            });
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的视图中做一些简单的循环:

<% for(var i=0; i<recentPosts.length; i++) { %>
    <% recentPosts[i].title %>
<% } %>
Run Code Online (Sandbox Code Playgroud)

以下是文档中适当位置的一些链接:https: //github.com/balderdashy/sails-docs/blob/0.9/reference/Configuration.md#expresshttps://github.com/balderdashy/sails-docs/斑点/ 0.9 /参考/ Response.md#reslocals