Как получить значение массива по индексу с помощью Handlebars.js?

Скажем, у меня JSON:

{
userinput: [
    {name: "brian", "value": "i like pies"},
    {name: "susan", "value": "memes are stupid"}
],
feedback: [
    {value: "i also like pies"},
    {value: "null"}
]
}

И я пытаюсь сделать таблицу следующим образом:

name ..... | input ......   | feedback
-----------|----------------|-----------------
brian      | I like pies    | I also like pies
susan      | mems are stupid| null

И хотя я понимаю, что было бы лучше иметь обратную связь как значение "userinput", то, что у меня есть, сделано не так...

Я пытаюсь получить индекс обратной связи внутри {{#each userinput}} `, например.

{{#each userinput}}
<td>{{name}}</td><td>{{value}}</td><td>{{../feedback[@index].value}}</td>
{{/each}}

Но, конечно, {{../feedback[@index].value}} не работает.

Каков наилучший способ (без изменения структуры json), чтобы захватить значение индекса соответствия внутри массива обратной связи?

Ответы

Ответ 1

Это можно выполнить с помощью помощника lookup:

Помощник lookup позволяет изменять динамическое значение параметра с помощью переменных Handlebars. Это полезно для определения значений для индексов массива.

Итак, шаблон для вашего примера будет выглядеть так:

{{#each userinput}}
    <td>{{name}}</td>
    <td>{{value}}</td>
    <td>
        {{#with (lookup ../feedback @index)}}
            {{value}}
        {{/with}}
    </td>
{{/each}}

Ответ 2

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

Я изменил "list" example, чтобы создать такой шаблон: "{{#list userinput feedback}}<td>{{name}}</td><td>{{value}}</td><td>{{@feedback.value}}</td>{{/list}}". Реализация подобна этому, принимая два параметра: "enter" и "обратная связь" (плюс стандартные "параметры" ).

Handlebars.registerHelper('list', function(input, feedback, options) {
  var out = "", data;

  // iterate over the input
  for (var i=0; i<input.length; i++) {
    if (options.data) {
      data = Handlebars.createFrame(options.data || {});

      // add "feedback" item to the current frame data
      data.feedback = feedback[i];
    }

    out += "<tr>" + options.fn(input[i], { data: data }) + "</tr>";
  }

  return out;
});

Здесь Fiddle.