如何使用Express/Node.js在所有视图中创建可访问的全局变量?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (124)

我用Jekyll构建了一个博客,可以在文件中定义_config.yml可在所有模板/布局中访问的变量。我正在使用Node.JS / Express与EJS模板和ejs-locals(用于partials / layouts)。

这是我目前在做的一个例子。

exports.index = function(req, res){
    res.render('index', { 
        siteTitle: 'My Website Title',
        pageTitle: 'The Root Splash Page',
        author: 'Cory Gross',
        description: 'My app description',
        indexSpecificData: someData
    });
};

exports.home = function (req, res) {
    res.render('home', {
        siteTitle: 'My Website Title',
        pageTitle: 'The Home Page',
        author: 'Cory Gross',
        description: 'My app description',
        homeSpecificData: someOtherData
    });
};

我希望能够在一个地方定义像网站标题,描述,作者等变量,并通过EJS访问它们,而无需将它们作为每个调用的选项传递给它们res.render。有没有办法做到这一点,并仍然允许我传递每个页面特有的其他变量?

提问于
用户回答回答于

我发现函数app.locals接受一个对象并将其所有属性存储为应用程序的全局变量。这些全局变量作为局部变量传递给每个视图。res.locals函数仅限于请求范围,因此响应局部变量只能访问该特定请求/响应期间呈现的视图。

app.js所做的就是补充:

app.locals({
    site: {
        title: 'ExpressBootstrapEJS',
        description: 'A boilerplate for a simple web application with a Node.JS and Express backend, with an EJS template with using Twitter Bootstrap.'
    },
    author: {
        name: 'Cory Gross',
        contact: 'CoryG89@gmail.com'
    }
});

访问site.titlesite.descriptionauthor.nameauthor.contact

我也可以为请求的每个响应定义局部变量res.locals,或者只是将诸如页面标题之类的变量作为调用中的options参数传递render

声明本地通过app.localsres.localsapp.locals变量之间的另一个区别是设置一个单一的时间,并坚持贯穿应用程序的整个生命周期。每次获得请求时都会设置它们。如果这个值没有改变,那么只需设置一次就可以提高效率。

用户回答回答于

可以通过将它们添加到通用中间件中的本地对象来完成此操作。

app.use(function (req, res, next) {
   res.locals = {
     siteTitle: "My Website's Title",
     pageTitle: "The Home Page",
     author: "Cory Gross",
     description: "My app's description",
   };
   next();
});

local也是一个扩大local对象而不是覆盖它的功能。所以下面的工作也是如此

res.locals({
  siteTitle: "My Website's Title",
  pageTitle: "The Home Page",
  author: "Cory Gross",
  description: "My app's description",
});

完整的例子

var app = express();

var middleware = {

    render: function (view) {
        return function (req, res, next) {
            res.render(view);
        }
    },

    globalLocals: function (req, res, next) {
        res.locals({ 
            siteTitle: "My Website's Title",
            pageTitle: "The Root Splash Page",
            author: "Cory Gross",
            description: "My app's description",
        });
        next();
    },

    index: function (req, res, next) {
        res.locals({
            indexSpecificData: someData
        });
        next();
    }

};


app.use(middleware.globalLocals);
app.get('/', middleware.index, middleware.render('home'));
app.get('/products', middleware.products, middleware.render('products'));

我还添加了一个通用的渲染中间件。这样你就不必为每条路由添加res.render,这意味着你有更好的代码重用。一旦你下了可重用的中间件路线,你会发现你将拥有大量的构建块,这将大大加快开发速度。

扫码关注云+社区

领取腾讯云代金券