【问题标题】:Return array of objects from Handlebars Helper从 Handlebars Helper 返回对象数组
【发布时间】:2017-02-18 20:14:00
【问题描述】:

我正在尝试编写一个帮助器,它将返回一个对象数组,然后可以循环访问这些对象。这是我现在拥有的:

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],而不是单个值。请帮忙:)

谢谢!

【问题讨论】:

  • 帮助器的目的是返回一个标记字符串,而不是返回数据。为什么你希望你的助手存储你的数据?
  • @76484 为了减少我正在编译的数据量,为了使服务器端编译更快,我希望能够只使用我需要的数据。
  • 你不编译数据。你编译模板。
  • 我明白,但是在帮助程序中,我会查询数据库,而我在编译模板时不必这样做
  • 将字符串编译成函数。这与查询数据库无关。如果您在服务器上呈现视图,那么看起来您想要实现的是将数据库查询从控制器层移动到视图层。这没有节省任何东西并且使代码更难理解。

标签: arrays node.js handlebars.js templating


【解决方案1】:

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

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

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

您正在为 entries 助手提供两件事: 1)当前上下文(this) 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) 应用这部分模板:

&lt;a href="/{{slug}}"&gt;{{title}}&lt;/a&gt;

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

这里有一个例子来展示这个工作。

<!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>

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

您可以在同一个 sn-p 中进行以下简单更改,将数据传递到您的模板:

<!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>

通过这种方式,您可以在 javascript 中检索您的数据,并按照预期的方式保留模板 - 制定 html。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    相关资源
    最近更新 更多