Nodejs 如果不使用layout模板,则每个页面上内置的导航栏显示登陆名都必须在render里定义出来?

Nodejs 如果不使用layout模板,则每个页面上内置的导航栏显示登陆名都必须在render里定义出来?

/* GET home page. */ router.get(’/’, function (req, res) { res.render(‘index’, { title: ‘Express’, user: req.session.user }); });

/* GET 详细页面. */ router.get(’/thread’, function(req, res) { res.render(‘index’, { title: ‘Express’, user: req.session.user }); }); 每个页面都用<% include decorate/navbar.ejs %>定义了导航栏, 登录后,返回首页显示登陆名需render参数,链接到下个页面,也必须手工添加到render参数.岂不是很麻烦.有没有无需重复赋值的?


3 回复

当然可以!如果你不想使用布局(layout)模板,但又希望避免在每个页面的渲染函数中重复定义相同的变量(例如 user),你可以考虑通过中间件来统一处理这些共享的数据。这样你就可以在中间件中设置这些变量,然后在视图中直接使用它们。

以下是一个简单的例子来说明如何实现这一点:

示例代码

  1. 创建中间件

    首先,你需要创建一个中间件来设置共享数据(如用户信息)。这个中间件可以在路由处理之前运行,并将用户信息添加到渲染上下文中。

    // middleware.js
    const setUserContext = (req, res, next) => {
      if (req.session && req.session.user) {
        res.locals.user = req.session.user;
      }
      next();
    };
    
    module.exports = setUserContext;
    
  2. 在应用中使用中间件

    在你的 Express 应用中引入并使用这个中间件。

    // app.js
    const express = require('express');
    const session = require('express-session');
    const setUserContext = require('./middleware');
    
    const app = express();
    
    // 设置 session 中间件
    app.use(session({
      secret: 'your-secret-key',
      resave: false,
      saveUninitialized: true
    }));
    
    // 使用自定义中间件
    app.use(setUserContext);
    
    // 定义路由
    const router = express.Router();
    
    router.get('/', function (req, res) {
      res.render('index', { title: 'Express' });
    });
    
    router.get('/thread', function (req, res) {
      res.render('thread', { title: 'Thread Detail' });
    });
    
    app.use('/', router);
    
    // 启动服务器
    app.listen(3000, () => {
      console.log('Server is running on port 3000');
    });
    
  3. 在视图中使用用户信息

    在你的 EJS 视图文件中,你可以直接使用 user 变量,而不需要在每个路由处理函数中手动传递它。

    <!-- views/index.ejs -->
    <!DOCTYPE html>
    <html>
    <head>
      <title><%= title %></title>
    </head>
    <body>
      <nav>
        <% if (user) { %>
          <span>Welcome, <%= user.name %></span>
        <% } else { %>
          <a href="/login">Login</a>
        <% } %>
      </nav>
      <h1><%= title %></h1>
    </body>
    </html>
    

解释

  • 中间件:通过创建一个中间件 setUserContext,我们在每次请求时检查是否有用户会话信息,并将其存储在 res.locals 对象中。res.locals 是一个对象,可以在所有视图中访问。

  • 路由处理:在路由处理函数中,我们不再需要显式地传递 user 参数。由于中间件已经设置了 user,我们只需要传递其他特定于该页面的数据。

  • 视图:在 EJS 模板中,我们可以直接使用 user 变量,而不需要在每个页面上重复传递它。

这种方法可以显著减少代码重复,提高可维护性。


通过静态/动态视图助手:

app.locals.title=‘bootrap3’; app.use(function(req, res, next) { res.locals.user=req.session.user; next(); });

在Node.js中,如果你不想使用layout模板,而希望避免在每个页面渲染时都手动传递用户信息,可以考虑将这些通用数据的处理封装在一个中间件或自定义函数中。这样,你就可以确保每次渲染页面时都能自动包含这些信息。

示例代码

中间件方法

  1. 创建一个中间件,用于设置全局变量,包括用户的登录名:
// middleware.js
function setGlobals(req, res, next) {
    res.locals.user = req.session.user || null;
    next();
}

module.exports = setGlobals;
  1. 在应用中使用该中间件
const express = require('express');
const router = express.Router();
const setGlobals = require('./middleware');

app.use(setGlobals); // 应用全局中间件

router.get('/', function (req, res) {
    res.render('index', { title: 'Express' });
});

router.get('/thread', function (req, res) {
    res.render('index', { title: 'Express' });
});
  1. 在视图文件中使用user变量
<!-- index.ejs -->
<!DOCTYPE html>
<html>
<head>
    <title><%= title %></title>
</head>
<body>
    <nav>
        <% if (user) { %>
            <span>Welcome, <%= user.name %></span>
        <% } else { %>
            <a href="/login">Login</a>
        <% } %>
    </nav>
    <!-- 页面其他内容 -->
</body>
</html>

通过这种方式,无论哪个路由被访问,user对象都会被自动添加到res.locals中,因此在视图文件中可以直接使用它。

解释

  • res.locals 是一个对象,可以在所有路由处理程序中访问,并且会被传递给视图引擎。
  • 通过在中间件中设置 res.locals.user,你确保了每次渲染页面时都能自动包含用户信息,从而避免了在每个路由处理程序中重复传递这些参数。

这种方法不仅简化了代码,还提高了代码的可维护性。

回到顶部