Как я могу получить индекс массива в шаблоне 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}
Можно ли получить индекс?
Ответы
Ответ 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>