如何使用快车/ Node.js的创建在所有视图访问的全局变量?(How to create glob

2019-09-02 07:47发布

好了,我已经建立了使用博客杰基尔 ,你可以定义在文件中的变量_config.yml这是在所有的模板/布局的访问。 我目前使用的Node.js / 快递与EJS模板和EJS本地人 (用于谐音/布局。我希望做类似像全局变量的东西site.title了在发现_config.yml如果有人熟悉哲基尔我有喜欢的网站的标题变量(而不是页面标题),作者/公司名称,它保持不变对所有我的网页。

下面是我目前在做什么的例子:

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 。 有没有办法做到这一点,还让我在专门用于每一页的其他变量传递?

Answer 1:

有机会学习后快递3 API参考多一点,我发现我一直在寻找。 具体的条目app.locals再远一点下来res.locals举行我所需要的答案。

我发现了自己的功能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调用。

编辑:此方法不会让你在你的中间件使用这些本地人。 我作为Pickels建议在下面的评论居然没碰上这一点。 在这种情况下,你需要在他的替代(和赞赏)回答创建一个中间件功能等。 您的中间件功能需要将其添加到res.locals每个响应,然后调用next 。 该中间件的功能将需要放在上面这需要使用这些当地人任何其他中间件。

编辑:通过宣布当地人之间的另一个区别app.localsres.locals是与app.locals变量设定一个时间,在整个应用程序的生命存在。 当你与当地人设置res.locals在你的中间件,这些设置每次你得到一个请求。 你应该基本上希望通过设置全局app.locals除非值取决于请求req传递到中间件变量。 如果该值不然后改变它会更有效率为它在短短的一次设置app.locals



Answer 2:

您可以通过将其添加到当地人在一般的中间件反对这样做。

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();
});

当地人也将延长当地人对象,而不是覆盖它的功能。 所以下面的作品,以及

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增加,这意味着你有更好的代码重用每条路线。 一旦你走了可重复使用的中间件路线,你会发现你将有很多积木,这将极大地加快发展。



Answer 3:

对于快递4.0我发现,使用应用程序级变量的作用有点不同 - 科里的回答并没有为我工作。

从文档: http://expressjs.com/en/api.html#app.locals

我发现,你可以声明一个全局变量的应用程序中

app.locals

app.locals.baseUrl = "http://www.google.com"

然后在你的应用程序,你可以访问这些变量与您的快递中间件可以在REQ对象访问它们

req.app.locals.baseUrl

console.log(req.app.locals.baseUrl)
//prints out http://www.google.com


Answer 4:

在您的app.js你需要添加这样的事

global.myvar = 100;

现在,在你想使用这个变量所有的文件,你可以访问它myvar



Answer 5:

一种方法通过更新要做到这一点app.locals变量在应用程序app.js

通过下面的一组

var app = express();
app.locals.appName = "DRC on FHIR";

获取/访问

app.listen(3000, function () {
    console.log('[' + app.locals.appName + '] => app listening on port 3001!');
});

从@RamRovi例子的屏幕截图略有增强阐述。



Answer 6:

你也可以使用“全局”

例:

声明如下:

  app.use(function(req,res,next){
      global.site_url = req.headers.host;   // hostname = 'localhost:8080'
      next();
   });

使用像这样的:在任何视图或EJS文件<%的console.log(SITE_URL); %>

在js文件CONSOLE.LOG(SITE_URL);



Answer 7:

我为了避免污染的全球范围内做的是创建一个脚本,我可以在任何地方包括。

// my-script.js
const ActionsOverTime = require('@bigteam/node-aot').ActionsOverTime;
const config = require('../../config/config').actionsOverTime;
let aotInstance;

(function () {
  if (!aotInstance) {
    console.log('Create new aot instance');
    aotInstance = ActionsOverTime.createActionOverTimeEmitter(config);
  }
})();

exports = aotInstance;

这样做只会一次创建一个新的实例和共享无处不在,其中包括文件。 我不知道这是否是因为变量是因为内部参考机制,为应用程序(可能包括缓存)的缓存或它。 节点是如何解决这个任何意见将是巨大的。

或许也看过这让如何要求工作要点: http://fredkschott.com/post/2014/06/require-and-the-module-system/



文章来源: How to create global variables accessible in all views using Express / Node.JS?