【问题标题】:Accessing Express.js req or session from Jade template从 Jade 模板访问 Express.js 请求或会话
【发布时间】:2011-09-13 23:27:45
【问题描述】:

我想知道是否有一种简单的方法可以从 Jade 模板中访问 Express.js 的 req 或 session 变量,而无需通过正常响应传递它。

或者这是唯一的方法?

res.render('/', {
    session: req.session
});

【问题讨论】:

    标签: node.js express pug


    【解决方案1】:

    虽然在 javascript 中总有一种方法可以逃脱作用域并向上爬,但我真的真的真的真的真的 强烈建议您另谋出路。

    考虑一下您要问的问题:我可以让我的视图了解我的控制器的内容吗?

    或者你真正要问的是:我可以让我的视图了解我的运行时的胆量吗?

    视图应该获取数据并将其转换为标记。而已。如果你做任何其他事情,你就做错了。我不在乎它有多“容易”。这就是接口的意义所在。准确定义要传递的内容,并方便将一件事替换为另一件事。

    【讨论】:

    • 我希望做的是使用会话来确定用户是否登录,因为这将改变网站所有部分的所有模板上的许多内容。所以我只是讨厌必须为网站上的每个模板传递“logged_in:req.session.logged_in”。从 php 的历史来看,我知道 Smarty 对此有一个推荐的解决方案,即使用 {$smarty.session.logged_in}。
    • 这是一个有点苛刻和无益的答案。我和其他人一样遵循一些严格的 MVC 准则,但在这种情况下,我们谈论的是 html 模板中的 if() 语句。当您考虑另一种选择是为已登录和未登录用户提供两个完全不同的模板时,破坏某些 MVC 就成了两害相权取其轻。
    • 不正确。我会从控制器传递数据,我不希望视图知道如何调用附加模型。我不介意具有分支逻辑或计数器/迭代器和循环的视图,但这就是它应该具有的所有逻辑。我只会传递数据,我与之交谈过的其他人也会传递数据来做 MVC
    • 所以现在会话是“运行时的胆量”?啊,我跟不上这个快节奏的 IT 世界:D
    • 看到大多数 node.js 程序不仅仅是“只是”视图和模型,是的。
    【解决方案2】:

    您需要创建一个dynamicHelper 以供 Express 使用。

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

    然后在您的模板中,您可以使用<%= session.logged_in %> 或其他任何内容。

    注意:在 Express 3 中不推荐使用 dynamicHelpers

    【讨论】:

    • 太棒了,这正是我需要的。谢谢!
    【解决方案3】:

    在 express 3.x 中,dynamicHelpers 已被删除,因此您需要结合使用中间件和res.locals。假设我们要在 /signup/new 视图中访问 req.query

    localQuery = function(req, res, next) {
      res.locals.query = req.query;
      next();
    };
    
    newSignup = function(req, res) {
      res.render('signup/new');
    };
    
    app.get('signup/new', localQuery, newSignup);
    

    现在任何使用localQuery 中间件的路由都将设置res.locals.query。然后可以在您的视图中以query 访问它。

    【讨论】:

    • 为此我头疼了好几个小时。你是一个救生员:)
    【解决方案4】:

    只需使用中间件。

    app.use(function (req, res, next) {
                var origRender = res.render;
                res.render = function (view, locals, callback) {
                    if ('function' == typeof locals) {
                        callback = locals;
                        locals = undefined;
                    }
                    if (!locals) {
                        locals = {};
                    }
                    locals.req = req;
                    origRender.call(res, view, locals, callback);
                };
                next();
    });
    

    之后,您可以使用“#{req}”在翡翠模板中引用它。

    假设你在 'req' 中有一个 'user' 对象,而 'user' 有一个方法 'isAnonymous', 如果你的 user.isAnonymous() 返回 true,

    p #{req.user.isAnonymous()}
    

    将呈现为:

    <p>true</p>
    

    【讨论】:

      【解决方案5】:

      只需添加

      app.use(express.cookieParser());
      app.use(express.session({secret: '1234567890QWERTY'}));
      app.use(function(req,res,next){
          res.locals.session = req.session;
          next();
      });
      

      之前

      app.use(app.router);
      

      让你的会话在翡翠中

      p #{session}
      

      【讨论】:

      • 谢谢。简单实用。
      • 可能是最好的答案!
      • 这该死的简单实用的TAT
      • 这不再有效。 0|server | Error: Most middleware (like cookieParser) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.
      【解决方案6】:

      这对我有用

      app.use(function(req,res,next){
         res.locals.user = req.user;
         next();
      });
      

      在哈巴狗或翡翠视图用户中

      #{user.email}
      

      【讨论】:

        【解决方案7】:

        您可以使用渲染函数来解决这个问题,在该函数中,您可以将需要会话变量的每个视图渲染为模板中可访问的局部变量(例如,通常在用户登录时)。

        这是一个函数示例,但您可以随意调整:

        var renderView = function(res, template, context, session, cb) {
            context.session = session;
        
            if(cb){
                res.render(template, context, function(error, html){
                    cb(error, html)
                }
            } else {
                res.render(template, context)
            }
        }
        

        那么就可以这样使用了:

        app.get("/url", function(req, res){
        
            req.session.user_email = user_email;
        
            renderView(res, "template_name", { local_variables: local_variables }, req.session)
        });
        

        在您的翡翠模板中,您可以像这样访问会话变量:

        div.user-email #{session.user_email}
        

        【讨论】:

          【解决方案8】:

          如果你的会话对象变量是全局声明的,那么 在全球

          变量会话

          在函数中

          sess=req.session

          req.render('index.pug',{sess})

          【讨论】:

            猜你喜欢
            • 2014-10-26
            • 1970-01-01
            • 1970-01-01
            • 2011-02-02
            • 1970-01-01
            • 2014-09-19
            • 2013-05-01
            • 1970-01-01
            相关资源
            最近更新 更多