Как использовать вложенные итераторы с Mustache.js или Handlebars.js? - PullRequest
34 голосов
/ 09 февраля 2012

Я хотел бы использовать handlebars.js или mustache.js, чтобы перебрать список семейств, а затем перебрать членов этой семьи. Внутри обоих циклов я хочу отобразить свойства обоих. Однако, как только я попаду во вторую итерацию, ни одна из переменных семейства не будет видна.

{{#each families}}
  {{#each members}}
    <p>{{ ( here I want a family name property ) }}</p>
    <p>{{ ( here I want a member name property ) }}</p>
  {{/each}}
{{/each}}

Возможно ли это? Буду очень признателен за любую помощь!

Ответы [ 5 ]

54 голосов
/ 11 февраля 2013

Извините, я немного опоздал в игре здесь.Принятый ответ великолепен, но я хотел бы добавить ответ, который, на мой взгляд, также полезен, особенно если вы перебираете простые массивы строк / столбцов.

Когда вы работаете с вложенными путями руля, вы можете использовать ../ для ссылки на родительский контекст шаблона ( см. Здесь для получения дополнительной информации).

Итакдля вашего примера вы можете сделать:

{{#each families}}
  {{#each members}}
    <p>{{../surname}}</p>
    <p>{{given}}</p>
  {{/each}}
{{/each}}

Это было особенно полезно для меня, потому что я делал сетку и хотел дать каждому квадрату имя класса, соответствующее его строке и положению столбца.Поэтому, если rows и columns просто возвращают массивы, я могу сделать это:

<tbody>
  {{#each rows}}                                                           
    <tr>
      {{#each columns}}
        <td class="{{this}}{{../this}}"></td>
      {{/each}}
    </tr>
  {{/each}}
</tbody>

Обновить

Это решение для руля.Комментарий ниже объясняет, почему он не будет работать в усах.

44 голосов
/ 10 февраля 2012

Вы можете легко вложить разделы со списками объектов. Используйте структуру данных, где families - это список, в котором есть объект members, в котором есть список любых объектов (или даже больше списков), например:

{
  "families" : [
        {
          "surname": "Jones",
          "members": [
            {"given": "Jim"},
            {"given": "John"},
            {"given": "Jill"}
          ]
        },
        {
          "surname": "Smith",
          "members": [
            {"given": "Steve"},
            {"given": "Sally"}
          ]
        }
      ]
}

Вы можете заполнить шаблон как:

<ul>
    {{#families}}
    <li>{{surname}}
      <ul>
        {{#members}}
        <li>{{given}}</li>
        {{/members}}
      </ul>
    </li>
    {{/families}}
  </ul>

jsFiddle в данный момент недоступен, поэтому вот полный рабочий HTML с JS:

<!DOCTYPE html>
<head>

  <script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.3.0/mustache.min.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script>
    $(function() {
      var tpl = $('#fam').html(),
        data = {
          "families" : [
            {
              "surname": "Jones",
              "members": [
                {"given": "Jim"},
                {"given": "John"},
                {"given": "Jill"}
              ]
            },
            {
              "surname": "Smith",
              "members": [
                {"given": "Steve"},
                {"given": "Sally"}
              ]
            }
          ]
        },
        html = Mustache.to_html(tpl, data);

        $("#main").append(html);

    });
  </script>

</head>

<div id="main"></div>

<script type="template/text" id="fam">
  <ul>
    {{#families}}
    <li>{{surname}}
      <ul>
        {{#members}}
        <li>{{given}}</li>
        {{/members}}
      </ul>
    </li>
    {{/families}}
  </ul>
</script>
5 голосов
/ 08 июля 2012

Отличный ответ @ maxbeatty.

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

Сначала у меня есть одномерный массив, которыйхотел разделить на каждые 4 элемента:

// this is the one dimensional data we have from let's say a mysql query
var array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', ...];

// think of it as [[], [], [], [], [], ...]
// but instead we'll be adding a dummy object with a dummyKey
// since we need a key to iterate on
var jagged = [];

var size = 4, // this is the size of each block
    total = array.length / block; // total count of all blocks
// slice the initial one dimensional array into blocks of 4 elements each
for (var i=0; i < total; i++) {
    jagged.push({dummyKey: array.slice(i*size, (i+1)*size)});
}

Теперь, если мы передадим jagged в наше представление, мы можем повторить это так:

<ul>
{{#jagged}}
    <li>
        <ul>
            {{#dummyKey}}
            <li>{{.}}</li>
            {{/dummyKey}}
        </ul>
    </li>
{{/jagged}}
</ul>

Если у нас заполнен наш начальный массивс объектами:

var array = [{key1: 'a', 
              key2: 'b'},
             {key1: 'c', 
              key2: 'd'},
             {key1: 'e', 
              key2: 'f'},
              ...
];

Тогда в нашем шаблоне мы будем иметь:

<ul>
{{#jagged}}
    <li>
        <ul>
            {{#dummyKey}}
            <li>{{key1}} - {{key2}}</li>
            {{/dummyKey}}
        </ul>
    </li>
{{/jagged}}
</ul>
3 голосов
/ 03 июня 2017

Для набора данных, подобного приведенному ниже:

{
  rows: 
    ["1A", "1B"], 
    ["2A", "2B"], 
    ["3A", "3B"]
}

следующее будет работать в усах:

<tbody>
    {{#rows}}
    <tr>
        {{#.}}
        <td>{{.}}</td>
        {{/.}}
    </tr>
    {{/rows}}
</tbody>
0 голосов
/ 22 октября 2017

Я искал ту же проблему, используя усы, и были даны ответы для рулей, а для усов требовался дополнительный JS, я знаю, что он старый, но я добавлю свой рабочий пример на тот случай, если кому-то еще это понадобится. Ура!

JSON:

"experience": [
     {
            "company": "Company 1",
            "position": "Graphic Designer",
            "tasks": ["Task 1", "Task 2", "Task 3"]
    },
     {
            "company": "Company 2",
            "position": "Graphic Designer",
            "tasks": ["Task 1", "Task 2", "Task 3", "Task 4", "Task 5"]
    }
]

ШАБЛОН:

{{#experience}}
        <h2>{{company}}</h2>
        <div class="position">{{position}}</div>
        <div class="occupazione">Responsabilities</div>
            <ul>
            {{#tasks}}
            <li>{{.}}</li>
            {{/tasks}}
            </ul>
 {{/experience}}
...