Подтвердить что ты не робот

Как я могу получить индекс массива в шаблоне Meteor каждый цикл?

Скажем, у меня есть объект, 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 напрямую, но undefined. Я также попытался использовать помощника:

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

но в этом вспомогательном getIndex, когда я console.log out this вижу:

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

Можно ли получить индекс?

4b9b3361

Ответ 1

метеоp >= 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}}

метеор 1.2

Когда-нибудь в будущем, пробелы могут предложить возможность определять индекс непосредственно в шаблоне. Однако, начиная с этой записи, единственным способом получить индекс является изменение результата, возвращаемого помощником. Например, вы могли бы getArray вернуть массив объектов, содержащих value и index, например:

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>

Также см. этот ответ для аналогичного примера с курсорами.

Стоит упомянуть, что вам, вероятно, не нужно хранить индекс в самой DOM через data-value, если только это не понадобится внешнему плагину. Как видно из приведенного ниже примера, каждый item имеет контекст с индексом. Для получения дополнительной информации см. это сообщение в блоге.

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

Ответ 2

Вы можете сделать это снова используемым помощником. Удобно иметь:

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

Ответ 3

Это изменение

Ответ 4

Вы можете изменить getArray, чтобы вернуть массив tupples и сохранить там индекс.

Ответ 5

Вот пример того, как вы можете просто добавить индекс к объекту и до тех пор, пока у вас не было ключа с именем index, прежде чем он не будет препятствовать чему-либо, этот способ работает только с массивами объектов. Теперь, если у вас есть массив значений, вы должны использовать ответ Кристана Фрица

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

Ответ 6

Вы также можете сделать это с подчеркиванием, предположив, что подписали свой шаблон на массив объектов

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>