如何从自定义车把助手访问请求对象

时间:2014-09-01 18:51:11

标签: javascript mustache handlebars.js

我正在使用带有node.js和express的把手,我有一个用于温度显示的自定义注册助手,我希望能够从页面URL访问查询参数。

帮助程序背后的概念是根据URL中是否?tempFormat=FtempFormat=C自动处理华氏度到摄氏度的转换。这是我想要的自定义助手的伪代码:

hbs.registerHelper("formatTemp", function(temp) {
    if (query parameter says to use Fahrenheit) {
        temp = toFahrenheitStr(temp);
    }
    return temp;
});

所以,我希望我的模板看起来像这样:

{{#each temperatures}}
    <div class="row {{{stripes @index}}}"> 
        <div class="time">{{prettifyDate t}}</div>
        <div class="atticTemp">{{formatTemp atticTemp}}</div>
        <div class="outsideTemp">{{formatTemp outsideTemp}}</div>
        <div class="spacer"></div>
    </div>
{{/each}}

我现在通过拉request.query.tempFormat并将其放入给予模板渲染的数据来解决此问题:

app.get('/debug', function(request, response) {
    var tempData = {
        temperatures: data.temperatures,
        units: request.query.tempFormat || "C"
    };
    response.render('debug', tempData);
});

然后,在模板中传递该数据:

{{#each temperatures}}
    <div class="row {{{stripes @index}}}"> 
        <div class="time">{{prettifyDate t}}</div>
        <div class="atticTemp">{{formatTemp atticTemp ../units}}</div>
        <div class="outsideTemp">{{formatTemp outsideTemp ../units}}</div>
        <div class="spacer"></div>
    </div>
{{/each}}

但是,这看起来很麻烦,因为我必须将温度单位传递给每个模板渲染调用,然后我必须将它们放在我希望它们被温度显示器使用的每个模板中。他们已经坐在请求对象中了。那么,我试图弄清楚如何从把手自定义助手功能访问请求对象?这样,我可以为每个渲染保存代码并在每个模板中保存代码,并且tempFormat查询参数只会自动应用于我的模板中对formatTemp的任何使用。

有没有人知道如何在不使用全局的情况下从把手自定义帮助程序访问请求对象?

3 个答案:

答案 0 :(得分:8)

首先,您需要通过在路径之前的任何位置注册中间件来将您的请求对象分配给本地响应

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

然后您可以访问助手中的查询对象

<div class="atticTemp">{{formatTemp atticTemp ../req.query.tempFormat }}</div>

答案 1 :(得分:0)

我正在使用快递把手包。您可以在其配置对象上注册帮助程序,如下所示。与您的方式略有不同,但您会明白这一点。为了简化这些事情,我刚刚在辅助函数中添加了第二个参数(:

var exphbs  = require('express-handlebars');

app.engine('handlebars', exphbs({
    defaultLayout: 'layout',
    helpers : {
        formatTemp: function(temp, unit) {
            console.log(unit);
            if (unit=="F") {
                return temp;
            } else {
                return 32 + (temp* 9 / 5);
            }
        }
    }

上下文数据结构和用法是相同的。

测试。

答案 2 :(得分:0)

  

Handlebars总是以此当前上下文来调用帮助程序,因此您可以以此来调用该块以评估当前上下文中的块。

     

https://handlebarsjs.com/block_helpers.html#basic-blocks

您可以将@Roland的答案与此功能结合使用,以使您的助手使用单个参数确定正确的格式。

首先添加一个中间件,将请求中的值注入到车把的上下文中。

app.use(function(req, res, next){
    var tempUnits = this.req.query.tempFormat || 'C';
    this.locals.tempUnits = tempUnits;
    next();
})

然后在中间件功能中,您可以使用this.tempUnits访问您注入的值。

hbs.registerHelper("formatTemp", function(temp) {
    var units = this.tempUnits;
    if (units == 'F') {
        temp = toFahrenheitStr(temp);
    }
    return temp;
});

然后,您就可以使用单个参数助手来从请求中获取数据。

<div class="atticTemp">{{formatTemp atticTemp}}</div>

注意:您可以 添加整个请求对象,但是让中间件注入所需的值比较干净。