如何在每个循环中获取Meteor模板中的数组索引?

时间:2014-06-14 23:06:46

标签: javascript meteor spacebars

说我有一个对象,someObject:

{
  foo: "apple",
  myArray: ["abc", "def"]
}

一个看起来像这样的模板助手(并且工作正常):

getArray: function(){
  var self = this;
  self.myArray = self.myArray || [];    
  return self.myArray;
}

我应该如何构造html来获取数组索引?

我试过了:

<template name="someObject"> // takes someObject as data
  {{#each getArray}}
    <div class="item" data-value="{{WHAT GOES HERE?}}">{{this}}</div>
  {{/each}}
</template>

在这种情况下this成功返回"abc""def"。这很好。但是如何才能将数组的索引放入属性data-value

我直接尝试this.index,但未定义。我也尝试过使用帮助器:

<template name="someObject"> // takes someObject as data
  {{#each getArray}}
    <div class="item" data-value="{{getindex}}">{{this}}</div>
  {{/each}}
</template>

但是当我在console.log getIndex时,在这个助手this中,我看到了:

String {0: "a", 1: "b", 2: "c", length: 3}
String {0: "d", 1: "e", 2: "f", length: 3}

是否可以获得索引?

6 个答案:

答案 0 :(得分:57)

meteor&gt; = 1.2

Spacebars在1.2中获得了很多功能,包括原生@index。不再需要助手来解决这个问题 - 您可以这样做:

{{#each getArray}}
  <div class="item" data-value="{{@index}}">{{this}}</div>
{{/each}}

或者,如果你想在帮助器中使用索引:

{{#each getArray}}
  <div class="item" data-value="{{someHelper @index}}">{{this}}</div>
{{/each}}

流星&lt; 1.2

将来的某个时候,空格键可以提供直接在模板中确定索引的功能。但是,在撰写本文时,获取索引的唯一方法是修改帮助程序返回的结果。例如,您可以让getArray返回包含valueindex的对象数组,如下所示:

getArray: function() {
  var self = this;
  self.myArray = self.myArray || [];
  return _.map(self.myArray, function(value, index){
    return {value: value, index: index};
  });
}

模板可以像这样使用索引:

<template name="someObject">
  {{#each getArray}}
    <div class="item" data-value="{{index}}">{{value}}</div>
  {{/each}}
</template>

有关游标的类似示例,请参阅this answer

值得一提的是,您可能不需要通过data-value将索引存储在DOM中,除非外部插件需要它。正如您在下面的示例中所看到的,每个item都有一个带索引值的上下文。有关详细信息,请参阅this blog post

Template.someObject.events({
  'click .item': function() {
    console.log(this.index);
  }
});

答案 1 :(得分:20)

您也可以将其作为可重复使用的助手。这很方便:

JS:

UI.registerHelper('addIndex', function (all) {
    return _.map(all, function(val, index) {
        return {index: index, value: val};
    });
});

HTML:

{{#each addIndex somearray}}
<div>
   {{index}}: {{value}}
</div>
{{/each}}

答案 2 :(得分:9)

This change is coming and you will be able to do {{@index}}. When meteor supports the most recent version of handlebars.

答案 3 :(得分:1)

您可以更改get Array以返回元组数组并将索引存储在那里。

答案 4 :(得分:0)

Here is an example of how you can just add index to the object and as long as you didnt have a key named index before it shouldnt obstruct anything this way works only with arrays of objects. Now if you have a array of values you should use Christan Fritz answer

UI.registerHelper("withIndex", function(obj) {
  obj = obj || [];
  _.each(obj, function (object, index) {
    obj[index].index = index;
  });
  return obj;
});

{#each withIndex fields}}
   <div class="form-group field" data-index="{{index}}">
      <label for="{{name}}">{{title}}</label> 
    </div>
{{/each}}

答案 5 :(得分:0)

您也可以使用下划线,假设您已将模板订阅到对象数组

Template.yourTemplate.helpers({
  objectsWithIndex: function() {
    _.map(this.objects, function(value, key) {
      return _.extend(value, {
        index: key
      });
    });
    return this.objects;
  }
});

并在你的HTML中......

<template name="someObject">
  {{#each objectsWithIndex}}
    <div class="item" data-value="{{index}}">{{value}}</div>
  {{/each}}
</template>