Handlebars/Mustache - 是否有内置的方法来循环遍历对象的属性?

IT技术 javascript handlebars.js mustache
2021-02-07 13:51:37

正如问题的标题所说,是否有一种循环对象属性的胡须/把手方式

所以与

var o = {
  bob : 'For sure',
  roger: 'Unknown',
  donkey: 'What an ass'
}

然后我可以在模板引擎做一些相当于

for(var prop in o)
{
    // with say, prop a variable in the template and value the property value
}

?

6个回答

自 Handlebars 1.0rc1 以来的内置支持

Handlebars.js 中已添加对此功能的支持,因此不再需要外部帮助程序。

如何使用它

对于数组:

{{#each myArray}}
    Index: {{@index}} Value = {{this}}
{{/each}}

对于对象:

{{#each myObject}}
    Key: {{@key}} Value = {{this}}
{{/each}}

请注意,只有通过hasOwnProperty测试的属性才会被枚举。

您如何仅针对特定的属性白名单执行此操作?
2021-03-17 13:51:37
@Rafi:不过,如果不了解您的数据结构,就无法理解这一点。
2021-03-28 13:51:37
如果没有记错,那么只有 v1.1.0 可用,但很好的回答谢谢。
2021-03-31 13:51:37
@qodeninja:简单:与您引用上述示例中的值的方式相同——使用{{#each this}}. 您对术语的选择也令人困惑(是什么使一个对象成为“顶级”而另一个不是?究竟什么是“预定义”键?等),因此您可能需要重新审视这些概念。
2021-04-01 13:51:37
@Rafi:你不是说 {{this.title}} 吗?
2021-04-02 13:51:37

作为助手实际上很容易实现:

Handlebars.registerHelper('eachProperty', function(context, options) {
    var ret = "";
    for(var prop in context)
    {
        ret = ret + options.fn({property:prop,value:context[prop]});
    }
    return ret;
});

然后像这样使用它:

{{#eachProperty object}}
    {{property}}: {{value}}<br/>
{{/eachProperty }}
看起来不错,您是否需要在循环内添加一个 hasOwnProperty 检查,这样您就不会迭代原型属性?
2021-03-22 13:51:37
很好的解决方案@Ben。如果有人试图将它与 Ember 一起使用,请参阅下面的答案以获取解决方案以使其正常工作。
2021-03-30 13:51:37

编辑:Handlebars 现在有一个内置的方法来完成这个;请参阅上面选择的答案使用普通 Mustache 时,以下内容仍然适用。

Mustache 可以遍历数组中的项目。所以我建议创建一个单独的数据对象,其格式设置为 Mustache 可以使用的方式:

var o = {
  bob : 'For sure',
  roger: 'Unknown',
  donkey: 'What an ass'
},
mustacheFormattedData = { 'people' : [] };

for (var prop in o){
  if (o.hasOwnProperty(prop)){
    mustacheFormattedData['people'].push({
      'key' : prop,
      'value' : o[prop]
     });
  }
}

现在,您的 Mustache 模板将类似于:

{{#people}}
  {{key}} : {{value}}
{{/people}}

在此处查看“非空列表”部分:https : //github.com/janl/mustache.js

最终同意您的建议,因为无论如何我都需要传递一些额外的子属性。谢谢您的帮助!
2021-03-27 13:51:37
非常感谢,你的想法让我又节省了一天寻找替代品的时间。这一行是关键 mustacheFormattedData = { 'people' : [] };
2021-04-10 13:51:37
您将如何使用“o”对象数组来执行此操作?
2021-04-10 13:51:37

这是@Ben 的答案,已更新以与 Ember 一起使用...请注意,您必须使用它,Ember.get因为上下文是作为字符串传入的。

Ember.Handlebars.registerHelper('eachProperty', function(context, options) {
  var ret = "";
  var newContext = Ember.get(this, context);
  for(var prop in newContext)
  {
    if (newContext.hasOwnProperty(prop)) {
      ret = ret + options.fn({property:prop,value:newContext[prop]});
    }
  }
  return ret;
});

模板:

{{#eachProperty object}}
  {{key}}: {{value}}<br/>
{{/eachProperty }}
谢谢@flynfish。context 是 Ember 中的一个字符串??这似乎……有点奇怪。
2021-04-05 13:51:37
是的,我不太确定,因为我是 Ember 的新手,并且仍在努力寻找解决方法。
2021-04-09 13:51:37

@Amit 的回答很好,因为它适用于 Mustache 和 Handlebars。

至于 Handlebars-only 解决方案,我已经看到了一些,我最喜欢https://gist.github.com/1371586 上each_with_key块助手

  • 它允许您迭代对象字面量而无需先重构它们,并且
  • 它使您可以控制所谓的关键变量。对于许多其他解决方案,您必须小心使用名为'key'、 或'property'等的对象键
不错的发现。只是对其他读者的警告:这个要点中的“key_value”助手有一个错误。阅读评论以了解如何修复它。
2021-03-12 13:51:37