从Handlebars Helper

时间:2017-02-18 20:14:00

标签: arrays node.js handlebars.js templating

我试图写一个帮助器,它将返回一个可以循环的对象数组。这就是我现在所拥有的:

Handlebars.registerHelper('testHelper', () => {
  return [
    { slug: 'Test', title: 'This is it!' },
    { slug: 'Test 2', title: 'This is the second it!' },
  ];
});

使用它像:

{{#entries this}}
  <a href="/{{slug}}">{{title}}</a>
{{/entries}}

我正在为数组中的每个对象而不是单个值接收[object, Object]。请帮助:)

谢谢!

1 个答案:

答案 0 :(得分:3)

Handlebars中帮手的工作方式有点棘手。您可以将与帮助程序相关的模板主体部分传递给帮助程序,而不是将数据从帮助程序传递到主模板主体。

因此,例如,当你这样做时:

{{#entries this}}
  <a href="/{{slug}}">{{title}}</a>
{{/entries}}

您向entries帮助者提供了两件事: 1)当前背景(本) 2)应用的一些模板逻辑

以下是帮助者获取这些项目的方式:

Handlebars.registerHelper('entries', (data, options) => {
  // data is whatever was provided as a parameter from caller
  // options is an object provided by handlebars that includes a function 'fn'
  //   that we can invoke to apply the template enclosed between 
  //   #entries and /entries from the main template
   :
   :
});

所以,要做你想做的事:

Handlebars.registerHelper('testHelper', (ignore, opt) => {
  var data = [
    { slug: 'Test', title: 'This is it!' },
    { slug: 'Test 2', title: 'This is the second it!' },
  ];
  var results = '';
  data.forEach( (item) => {
    results += opt.fn(item);
  });
  return results;
});

opt.fn(item)适用此部分模板:

<a href="/{{slug}}">{{title}}</a>

并且想法是创建一个字符串(html的一部分)然后返回并放入由主模板制定的字符串中。

以下是展示此工作的示例。

&#13;
&#13;
<!DOCTYPE html>
<html>
<head>
    <title>Page Title</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.js"></script>
</head>
<body>

<script id="t" type="text/x-handlebars">
    {{#testHelper this}}
    <a href="/{{slug}}">{{title}}</a>
    {{/testHelper}}
</script>

<script>
    Handlebars.registerHelper('testHelper', (ignore, opt) => {
        var data = [
            { slug: 'Test', title: 'This is it!' },
            { slug: 'Test 2', title: 'This is the second it!' },
        ];
        var results = '';
        data.forEach((item) => {
            results += opt.fn(item);
        });
        return results;
    });

    var t = Handlebars.compile($('#t').html());
    $('body').append(t({}));
</script>
</body>
</html>
&#13;
&#13;
&#13;

让我也回应别人试图告诉你的事情。尝试在模板中填充数据并没有多大意义。这应该作为模板的上下文传递。否则,您将业务逻辑与模板逻辑(视图)混合在一起,这会使事情变得不必要。

以下是您可以在同一代码段中进行的简单更改,将数据传递到模板:

&#13;
&#13;
<!DOCTYPE html>
<html>
<head>
    <title>Page Title</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.js"></script>
</head>
<body>

<script id="t" type="text/x-handlebars">
    {{#testHelper this}}
    <a href="/{{slug}}">{{title}}</a>
    {{/testHelper}}
</script>

<script>
    Handlebars.registerHelper('testHelper', (ignore, opt) => {
        var results = '';
        data.forEach((item) => {
            results += opt.fn(item);
        });
        return results;
    });

    var data = [
        { slug: 'Test', title: 'This is it!' },
        { slug: 'Test 2', title: 'This is the second it!' },
    ];
    var t = Handlebars.compile($('#t').html());
    $('body').append(t(data));
</script>
</body>
</html>
&#13;
&#13;
&#13;

通过这种方式,您可以在javascript中检索数据并保留模板以实现预期目标 - 制定HTML。