Как использовать вложенные итераторы с Mustache.js или Handlebars.js?
Я хотел бы использовать 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}}
Возможно ли это? Я бы очень признателен за любую помощь!
Ответы
Ответ 1
Вы можете легко встраивать разделы списков объектов. Используйте структуру данных, где 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>
Ответ 2
Жаль, что я немного опаздываю в игре здесь. Принимаемый ответ велик, но я хотел бы добавить ответ, который, как мне кажется, также полезен, особенно если вы повторяете простые массивы строк/столбцов.
Когда вы работаете с вложенными путями ручек, вы можете использовать ../
для ссылки на контекст родительского шаблона (см. здесь для более информация).
Итак, для вашего примера вы можете сделать:
{{#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>
Обновление
Это решение для Handlebars. Комментарий ниже объясняет, почему он не будет работать в Усах.
Ответ 3
Отличный ответ @maxbeatty.
Я просто хотел добавить еще один пример, если у кого-то такая же проблема, и он не может понять вышеупомянутое решение.
Сначала у меня есть один размерный массив, который я хотел разбить на каждые 4 элемента:
// this is the one dimensional data we have from let 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>
Ответ 4
Для набора данных, как показано ниже:
{
rows:
["1A", "1B"],
["2A", "2B"],
["3A", "3B"]
}
следующая работа будет работать в усатых:
<tbody>
{{#rows}}
<tr>
{{#.}}
<td>{{.}}</td>
{{/.}}
</tr>
{{/rows}}
</tbody>
Ответ 5
Я искал ту же проблему, используя усы, и ответы были даны для дескрипторов, а для усов требовалось дополнительное 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"]
}
]
TEMPLATE
{{#experience}}
<h2>{{company}}</h2>
<div class="position">{{position}}</div>
<div class="occupazione">Responsabilities</div>
<ul>
{{#tasks}}
<li>{{.}}</li>
{{/tasks}}
</ul>
{{/experience}}