javascript Express.js 查看“全局变量”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4718818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 14:39:42  来源:igfitidea点击:

Express.js View "globals"

javascriptnode.jsexpress

提问by Dominic Barnes

I'm using Express.js (on Node.js) and I know that you can render a view with custom data via the "locals" parameter. (res.render("template", { locals: { foo: "bar" } });)

我正在使用 Express.js(在 Node.js 上),我知道您可以通过“locals”参数呈现带有自定义数据的视图。( res.render("template", { locals: { foo: "bar" } });)

Is there any way to have "globals"? (ie. data that's accessible to every view)

有没有办法拥有“全局”?(即每个视图都可以访问的数据)

I saw view options, but that isn't recursive, so it replaces the locals I set if I use any locals with my template.

我看到了view options,但这不是递归的,所以如果我在模板中使用任何本地人,它会替换我设置的本地人。

This is my use case: I want to make it so that CSS/JS files can be added on a per-page basis, and that is part of my main layout. The problem is, if I don't explicitly set those arrays on every render, I get an undefined error, so in my template I always have to do the typeof css !== "undefined"dance. Additionally, I have other select box option lists that I don't want to have to explicitly add to each of my forms.

这是我的用例:我想让它可以在每页的基础上添加 CSS/JS 文件,这是我的主要布局的一部分。问题是,如果我没有在每次渲染时明确设置这些数组,我就会得到一个未定义的错误,所以在我的模板中,我总是不得不typeof css !== "undefined"跳舞。此外,我还有其他选择框选项列表,我不想将它们显式添加到我的每个表单中。

回答by tigerFinch

It's worth noting for those who may have come across this question since the release of Express 3, that the method 'dynamicHelpers' no longer exists.

对于那些自 Express 3 发布以来可能遇到过这个问题的人来说,值得注意的是,“dynamicHelpers”方法不再存在。

Instead you can use the app.locals function, which acts as an object you can store values or functions in, and then makes them available to views. For example:-

相反,您可以使用 app.locals 函数,该函数充当您可以在其中存储值或函数的对象,然后将它们提供给视图。例如:-

// In your app.js etc.
app.locals.title = "My App";
app.locals({
    version: 3,
    somefunction: function() {
        return "function result";
    }
});

// Then in your templates (shown here using a jade template)

=title
=version
=somefunction()  

// Will output

My App
3
function result

If you need access to the request object to pull information from, you can write a simple middle-ware function and use the app.settings variable.

如果您需要访问请求对象以从中提取信息,您可以编写一个简单的中间件函数并使用 app.settings 变量。

For example, if you are using connect-flash to provide messages to your users, you might do something like this:

例如,如果您使用 connect-flash 向用户提供消息,您可以执行以下操作:

app.use(function(req, res, next) {
    app.set('error', req.flash('error'));
    next();
});

Which would give you access to the error message with =settings.error in your template.

这将使您可以访问模板中带有 =settings.error 的错误消息。

These topics are covered here, albeit slightly briefly: http://expressjs.com/api.html#app.locals

这些主题在此处进行了介绍,尽管略为简短:http: //expressjs.com/api.html#app.locals

Update: Express 4

更新:快递 4

app.localsis now a simple JavaScript Object, so every property has to be set one by one.

app.locals现在是一个简单的 JavaScript 对象,因此每个属性都必须一一设置。

app.locals.version = 3;
app.locals.somefunction = function() {
    return "function result";
}

res.localsprovides the exact same functionality, except it should be used for request-specific data rather than application-wide data. A user object or settings is a common use case.

res.locals提供完全相同的功能,除了它应该用于特定于请求的数据而不是应用程序范围的数据。用户对象或设置是一个常见的用例。

res.locals.user = req.isAuthenticated() ? req.user : null;
res.locals.userSettings = {
    backgroundColor: 'fff'
}

回答by alessioalex

There is a way to have "global" variables for views, using dynamic view helpers.

有一种方法可以使用动态视图助手为视图设置“全局”变量。

From the Express.js guide:

来自 Express.js 指南:

app.dynamicHelpers(obj)

Registers dynamic view helpers. Dynamic view helpers are simply functions which accept req, res, and are evaluated against the Server instance before a view is rendered. The return value of this function becomes the local variable it is associated with.

app.dynamicHelpers({ session: function(req, res){ return req.session; } });

All views would now have session available so that session data can be accessed via session.name etc:

app.dynamicHelpers(obj)

注册动态视图助手。动态视图助手是简单的函数,它们接受 req、res 并在呈现视图之前根据服务器实例进行评估。此函数的返回值成为与其关联的局部变量。

app.dynamicHelpers({ session: function(req, res){ return req.session; } });

所有视图现在都可以使用会话,以便可以通过 session.name 等访问会话数据:

You can find a real example on how to use them here: https://github.com/alessioalex/Nodetuts/tree/master/express_samples(node app.js to start the app)

您可以在此处找到有关如何使用它们的真实示例:https: //github.com/alessioalex/Nodetuts/tree/master/express_samples(用于启动应用程序的节点 app.js)

回答by mikl

A real-world example of using view options as the author mentioned:

作者提到的使用视图选项的真实示例:

var app = express.createServer();

app.configure(function() {
  app.set('views', path.join(__dirname, '..', 'views'));
  app.set('view engine', 'jade');
  app.set('view options', {
    assetVersion: 1
  });

And then in my layout.jade (base template for the app in my case):

然后在我的 layout.jade(在我的例子中应用程序的基本模板):

link(rel='stylesheet', href='/static/css/' + assetVersion + '/style.css')
script(src='/static/js/' + assetVersion + '/script.js')

With this little trick, I only have to update the assetVersionvariable one place to make sure that my assets aren't cached in Varnish or other places.

通过这个小技巧,我只需要在assetVersion一个地方更新变量,以确保我的资产不会缓存在 Varnish 或其他地方。

回答by Dominic Barnes

I wound up looking into the source code, and I've actually found that this is now possible in never versions of Express. (so far, only available through GitHub)

我最终查看了源代码,实际上我发现这在从来没有版本的 Express 中是可能的。(到目前为止,只能通过 GitHub 获得)

回答by Daniel Beardsley

The simplest way to accomplish this is to create a variable that represents the default set of locals for your views. Then create a function that accepts an object, merges it with the locals, and returns the merged object.

完成此操作的最简单方法是创建一个变量来表示您的视图的默认局部变量集。然后创建一个函数,它接受一个对象,将它与本地人合并,并返回合并后的对象。

I also pass ALL my locals inside a container objecti.e. {locals:{g:{prop:val}}}so in my views I can refernce g.propwhich will just return nullwhen it isn't set, instead of throwing an undefined error.

我还将所有本地对象传递到容器对象中,{locals:{g:{prop:val}}},在我的视图中,我可以引用g.prop它,null当它未设置时将返回,而不是抛出未定义的错误。

function default_page_vars(custom_vars){
    var vars = {
        footer: true,
        host: req.headers.host.split(':')[0],
        config: this.config
    };

    if(custom_vars){
        for(var k in custom_vars){
            vars[k] = custom_vars[k];
        }
    }
    return {
        g:vars
    };
}

//within your handler
response.render(view, {
    locals: default_page_vars(other_locals)
});

回答by Michael Cole

This is a buried response, but I finally got it to work.

这是一个隐藏的响应,但我终于让它起作用了。

1) This is an example around the module connect-flash

1) 这是一个关于模块连接闪存的例子

2) Add a piece of middleware in server.js/app.js to add reqto locals. This allows the template to call request.flash()whenever it needs. Without this, flash()gets consumed on each request/redirect defeating the purpose.

2)在server.js/app.js中添加一个中间件,添加reqlocals. 这允许模板在需要request.flash()时调用。没有这个,flash()每个请求/重定向都会消耗掉目的。

var app = module.exports = express()
  , flash=require('connect-flash');
app.configure(function(){
  ...
  app.use(express.session({ secret: "shhh" }));

  // Start Router
  app.use(flash());
  app.use(function(req, res, next) {
    res.locals.request = req;
    next();
  });

  app.use(app.router);
});

3) Setup your route as normal (this is coffeescript, but nothing special)

3)像往常一样设置你的路线(这是coffeescript,但没什么特别的)

app.get '/home', (req, res) ->
  req.flash "info", "this"
  res.render "#{__dirname}/views/index"

4) Call request.flash() when you want the messages. They are consumed on each call, so don't console.log them or they'll be gone :-)

4) 当您需要消息时调用 request.flash()。它们在每次调用时都会被消耗,所以不要 console.log 它们,否则它们就会消失:-)

!!!
html
  head
    title= config.appTitle
    include partials/_styles

  body
    include partials/_scripts

    #header
      a(href="/logout") Logout CURRENTUSER
      h2= config.appTitle

    #messages
      - var flash = request.flash()
      each flashType in ['info','warn','error']
        if flash[flashType]
          p.flash(class=flashType)
            = flash[flashType]


    block content
      h1 content here

回答by Drozerah

Express 4

快递4

You can access local variables in templates rendered within the application.

您可以访问应用程序内呈现的模板中的局部变量。

So, if you want to use any locals in your template => assuming you have a template engine npm installed to your node/express application.

因此,如果您想在模板中使用任何本地变量 => 假设您已将模板引擎 npm 安装到您的 node/express 应用程序中。

First, you need to set the express locals objectswith your custom variables in your app.jsfile, you can use an object if multiple values are needed (our case in this post)

首先,您需要在文件中使用自定义变量设置express locals 对象app.js如果需要多个值,您可以使用一个对象(本文中的案例)

 /**
  *  Set locals object
  */

 app.locals.layoutData = { 
  site: {
      title: 'MyWebSiteTitle',
  },   
  metaTag: {
      charset: 'UTF-8',
      description: 'MyDescription',
      keywords: 'keyword-1,keyword-2,...',
      author: 'MyName',
      viewport: 'width=device-width, initial-scale=1.0'
  }
 };

Then, to access the values in the template file layout.pug(in the case of PUG template engine for instance)

然后,访问模板文件中的值layout.pug(例如在 PUG 模板引擎的情况下)

doctype html
html
  head
    //title
    title #{locals.layoutData.site.title}
    //Describe metadata
    meta(charset=layoutData.metaTag.charset)
    meta(name='description', content=locals.layoutData.metaTag.description)
    meta(name='keywords', content=locals.layoutData.metaTag.keywords)
    meta(name='author', content=locals.layoutData.metaTag.author)
    meta(name='viewport', content=locals.layoutData.metaTag.viewport)
  body
      block content
      br
      hr
      footer
        p All rights reserved © 2018 |  #{locals.layoutData.site.title}

Tested with

测试过

  "dependencies": {
    "express": "^4.16.3",
    "pug": "^2.0.3"
  }