为什么我不能在 express handlebars 模板中使用 if 语句?

Why can't I use a if statement inside of my express handlebars template?

我最近开始从事我的第一个 Express 项目,我选择使用 Handlebars 作为我的模板语言,因为我在创建 Ghost 博客主题时有一些先前的经验。

我正在使用 Passport.js 和 connect-flash 创建登录屏幕以向用户发送错误消息。我能够将错误消息作为车把帮助程序传递得很好,但是当我尝试在车把模板中包含 if 语句时,即使出现错误消息,它也始终为 false。

这是我的代码:

login.js(路线)

app.route('/login')
    .get(function(req, res) {
        if (req.isAuthenticated()) {
            res.redirect('/');
        } else {
            res.render('login', {
                helpers: {
                    message: req.flash('loginMessage')
                }
            });
        }
    })
    .post(...);

login.handlebars

<form action="/login" method="post">
    <div>
        <label>Email</label>
        <input type="text" name="email">
    </div>
    <div>
        <label>Password</label>
        <input type="password" name="password"> 
    </div>
    <button type="submit">Log In</button>
</form>

{{#if message}}
    <p style="color: red">{{message}}</p>
{{/if}}

这在没有 if 语句的情况下有效:

<p style="color: red">{{message}}</p>

但我不喜欢在我的 html 中使用空元素的想法。任何帮助将不胜感激,因为我确信我遗漏了一些非常简单的东西。

谢谢。

我相信您必须使用 subexpression 才能在一个小胡子中调用多个助手。修复就像添加括号一样简单:

{{#if (message)}}
    <p style="color: red">{{message}}</p>
{{/if}}

编辑

请注意,上面假设 helpers.message 处的对象类型是一个函数,因为 Handlebars documentation states that helpers are functions. However, the connect-flash documentation 表明 req.flash('loginMessage') 将 return 一个数组。在这种情况下,结果不应分配给助手,而应该是视图模型对象的常规值:

res.render('login', {
    messages: req.flash('loginMessage')
});

在我们的模板中,由于 messages 是一个数组,我们必须查找并访问它的第 0 个元素:

{{#if (lookup messages 0)}}
    <p style="color: red">{{messages.[0]}}</p>
{{/if}}

这可能来得太晚了,但是对于那些将来仍然会遇到这个或相关问题的人,我希望这对你有用。 另一种方法是使用 res.redirect('/login'); 而不是 res.render('login).

将此添加到您的 SERVER/INDEX.JS

const flash = require('connect-flash');//import this guy
    app.use(flash());
    app.use(function(req, res, next) {
    res.locals.message = req.flash('loginMessage'); 
    next();
  });

您的 LOGIN.JS 将如下所示

  app.route('/login')
   .get(function(req, res) {
     if (req.isAuthenticated()) {
        res.redirect('/');
        return;//you should always return if there's no more thing to do
     } else {
       req.flash('loginMessage', 'your message here');
       res.redirect('/login');
       return;//you should always return if there's no more thing to do
    };
  })
  .post(...);

上述方法使您可以更轻松地重复使用您的消息。例如,您可以通过将 req.flash('loginMessage', 'your message here'); 更改为此 req.flash('loginMessage', 'another message here'); 来重用上述消息。

您还可以通过将所有错误和成功消息移动到一个 PARTIAL 文件夹中,然后通过在所有页面中插入此 {{>yourMessages}} 在前端的所有其他页面中使用它来重用整个消息。

你的LOGIN.handlebars

 <form action="/login" method="post">
   <div>
    <label>Email</label>
    <input type="text" name="email">
   </div>
   <div>
    <label>Password</label>
    <input type="password" name="password"> 
   </div>
   <button type="submit">Log In</button>
 </form>

 {{#if message}}
  <p style="color: red">{{message}}</p>
 {{/if}}