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

Индекс элемента массива в Mustache.js

Это то, что я хотел бы сделать в Mustache.js, но не видя, как с документацией.

var view = {items:['Mercury','Venus','Earth','Mars']};
var template = "<ul> {{#items}}<li>{{i}} - {{.}}</li>{{/items}} </ul>";
var html = Mustache.to_html(template,view);

Требуемый вывод:

<ul>
  <li>0 - Mercury</li>
  <li>1 - Venus</li>
  <li>2 - Earth</li>
  <li>3 - Mars</li>
</ul>
4b9b3361

Ответ 1

Альтернативное решение, не обманывая Mustache.js

Вместо того, чтобы обманывать усы, вы можете использовать <ol></ol> вместо <ul></ul>, который будет префикс каждого элемента index+1.

Если вы хотите использовать css, чтобы изменить начальный номер на 0, он будет отображаться точно так, как вы хотите. Вы даже можете изменить dot после номера, на что-то вроде " - ", и проблема будет решена.

<ol>
  <li>Mercury</li>
  <li>Venus</li>
  <li>Earth</li>
  <li>Mars</li>
</ol>

выше будет отображаться как:

1. Mercury
2. Venus
3. Earth
4. Mars

способ Mustache.js сделать это

Правильный метод, если вы хотите сделать это в усах, - это преобразовать массив строк в массив объектов, где присутствует индекс и строковое значение.

// I wrote this from the back of my head, it untested and not guaranteed
// to work without modifications, though the theory behind it is valid.


var array     = ["123","stackoverflow","abc"];
var obj_array = [];

for (idx in array)
   obj_array.push ({'index': idx, 'str': array[idx]});

var view     = {items: obj_array};
var template = "<ul>{{#items}}<li>{{index}} - {{str}}</li>{{/items}}</ul>";
var html     = Mustache.to_html(template,view);

Ответ 2

Ищете быстрое решение?

Просто добавьте функцию index

var data = {
    items: [{
            name: Aliasghar
            , grade: 19
        }, {
            name: Afagh
            , grade: 20
    }]
    , index: function() {
        return ++window['INDEX']||(window['INDEX']=0);
    }
}

и ваш шаблон может выглядеть следующим образом:

{{#items}}
    {{index}} -- {{name}} is {{grade}}
{{/items}}

Как это работает

Мы добавляем index: function(){} к данным, и мы используем его как обычную функцию в шаблоне. Эта функция добавляет ключ к объекту window, который доступен глобально; затем увеличивает его один за другим.

Для использования с несколькими списками

Обратите внимание, что если вы используете несколько шаблонов один за другим, вам нужно либо reset window['INDEX'], либо изменить его на что-то еще, например window['YEKI_DIGE']. Другой способ сделать это - добавить функцию resetIndex. Вот как это сделать:

var data = {
    items: [{
            name: Aliasghar
            , grade: 19
        }, {
            name: Afagh
            , grade: 20
    }]
    , index: function() {
        return ++window['INDEX']||(window['INDEX']=0);
    }
    , resetIndex: function() {
        window['INDEX']=null;
        return;
    }
}

и ваш шаблон может выглядеть следующим образом:

{{#items}}
    {{index}} -- {{name}} is {{grade}}
{{/items}}
{{resetIndex}}

Вдохновленный этим ответом: fooobar.com/questions/111713/... из dave в В Mustache, Как получить индекс текущего раздела

Ответ 4

Если вы хотите получить доступ к индексу несколько раз за элемент, я бы предложил что-то вроде следующего.

var data = {
    items: [{
        name: Aliasghar
        , grade: 19
    }, {
        name: Afagh
        , grade: 20
    }]
    , setUpIndex: function() {
        ++window['INDEX']||(window['INDEX']=0);
        return;
    }
    , getIndex: function() {
        return window['INDEX'];
    }
    , resetIndex: function() {
        window['INDEX']=null;
        return;
    }
}
  • Используйте функцию restIndex перед повторением каждого списка в Mustache.
  • Используйте функцию setUpIndex в начале каждого элемента списка, чтобы настроить индекс для этого элемента.
  • Используйте элемент getIndex для доступа к индексу.

В качестве примера рассмотрим это.

{{resetIndex}}
{{#items}}
    {{setUpIndex}}
    {{getIndex}}. {{name}} is at index {{getIndex}}
{{/items}}

Обратите внимание, что вы можете получить доступ к индексу более одного раза за элемент без получения неправильного значения.

Ответ 5

(Протестировано в node 4.4.7, усы 2.2.1.)

Если вам нужен хороший чистый функциональный способ, который не включает глобальные переменные или мутирует сами объекты, используйте эту функцию;

var withIds = function(list, propertyName, firstIndex) {
    firstIndex |= 0;
    return list.map( (item, idx) => {
        var augmented = Object.create(item);
        augmented[propertyName] = idx + firstIndex;
        return augmented;
    })
};

Используйте его, когда вы собираете свое представление;

var view = {
    peopleWithIds: withIds(people, 'id', 1) // add 'id' property to all people, starting at index 1
};

Оптимальный подход к этому подходу состоит в том, что он создает новый набор объектов "viewmodel", используя старый набор в качестве прототипов. Вы можете прочитать person.id так же, как вы читали бы person.firstName. Однако эта функция не изменяет ваши объекты людей вообще, поэтому другой код (который, возможно, полагался на свойство ID, не находясь там), не будет затронут.

Ответ 6

Вы можете использовать Handlerbars.js, затем

Handlebars.registerHelper("inc", function (value, options) {
    return parseInt(value) + 1;
});

Использовать его в HTML

{{inc @@index}}