Главная страница   /   12.7. Управление итерацией по массивам (Pro jQuery

Pro jQuery

Pro jQuery

Адам Фриман

12.7. Управление итерацией по массивам

Тег шаблона {{each}} позволяет получить контроль над тем, как в шаблоне обрабатываются массивы с данными. Это альтернативный подход к использованию вложенных шаблонов, который я показал вам раньше в этой главе. В листинге 12-20 показано, как используется тег {{each}}.

Листинг 12-20: Использование шаблонного тега {{each}}
<script type="text/javascript">
	$(document).ready(function () {
		var originalData = [
			{ name: "Astor", product: "astor", stocklevel: "10", price: 2.99 },
			{ name: "Daffodil", product: "daffodil", stocklevel: "12", price: 1.99 },
			{ name: "Rose", product: "rose", stocklevel: "2", price: 4.99 },
			{ name: "Peony", product: "peony", stocklevel: "0", price: 1.50 },
			{ name: "Primula", product: "primula", stocklevel: "1", price: 3.12 },
			{ name: "Snowdrop", product: "snowdrop", stocklevel: "15", price: 0.99 },
		];

		var itemsPerRow = 3;
		var slicedData = [];

		for (var i = 0, j = 0; i < originalData.length; i += itemsPerRow, j++) {
			slicedData.push({
				rowid: "row" + j,
				flowers: originalData.slice(i, i + itemsPerRow)
			});
		}

		$('div.drow').remove();
		$('#flowerTmpl').tmpl(slicedData).appendTo('div.dtable');
	});

	function stockDisplay(product) {
		return product.stocklevel > 0 ? 1 : 0;
	}
</script>
<script id="flowerTmpl" type="text/x-jquery-tmpl">
	<div id="${rowid}" class="drow">
		{{each flowers}}
			<div class="dcell">
				<img src="${product}.png" />
				<label for="${product}">${$index} ${name}: </label>
				<input name="${product}" value="${stockDisplay($value)}" required />
			</div>
		{{/each}}
	</div>
</script>

Содержание между тегами {{each}} и {{/each}} выполняется один раз для каждого элемента в указанном массиве. Между тегами {{each}} и {{/each}} вы можете обращаться, как обычно, к отдельным свойствам. Можно обращаться к текущему элементу массива, используя переменную $value, и к индексу текущего элемента, используя переменную $index.

Совет

Можно указать различные имена для $index и $value, если передать аргументы в тег {{each}}. Например, если вы хотите $i вместо $index и $v вместо $value, нужно написать {{each($i, $v) flowers}}.

Итерации по результату выражения

В тег {{each}} можно передать выражение, тогда содержание вплоть до {{/each}} будет воспроизводиться для каждого элемента результата данного выражения. В листинге 12-21 показана эта технология, где я выбираю набор элементов данных, чтобы удалить те, которых нет в наличии или их очень мало.

Листинг 12-21: Использование выражения с тегом {{each}}
<script type="text/javascript">
	$(document).ready(function () {
		var originalData = [
			{ name: "Astor", product: "astor", stocklevel: "10", price: 2.99 },
			{ name: "Daffodil", product: "daffodil", stocklevel: "12", price: 1.99 },
			{ name: "Rose", product: "rose", stocklevel: "2", price: 4.99 },
			{ name: "Peony", product: "peony", stocklevel: "0", price: 1.50 },
			{ name: "Primula", product: "primula", stocklevel: "1", price: 3.12 },
			{ name: "Snowdrop", product: "snowdrop", stocklevel: "15", price: 0.99 },
		];
		var itemsPerRow = 3;
		var slicedData = [];
		for (var i = 0, j = 0; i < originalData.length; i += itemsPerRow, j++) {
			slicedData.push({
				rowid: "row" + j,
				flowers: originalData.slice(i, i + itemsPerRow)
			});
		}
		$('div.drow').remove();
		$('#flowerTmpl').tmpl(slicedData).appendTo('div.dtable');
	});
	function stockDisplay(product) {
		return product.stocklevel > 0 ? 1 : 0;
	}
	function filterLowStock(flowers) {
		var result = [];
		for (var i = 0; i < flowers.length; i++) {
			if (flowers[i].stocklevel > 2) { 
				result.push(flowers[i]) 
			}
		}
		return result;
	}
</script>
<script id="flowerTmpl" type="text/x-jquery-tmpl">
	<div id="${rowid}" class="drow">
		{{each filterLowStock(flowers)}}
			<div class="dcell">
				<img src="${product}.png" />
				<label for="${product}">${name}: </label>
				<input name="${product}" value="${stockDisplay($value)}" required />
			</div>
		{{/each}}
	</div>
</script>

Я вызываю функцию filterLowStock из тега {{each}}, которая ограничивает число элементов, над которыми происходит итерация. Результат можно увидеть на рисунке 12-8.

Рисунок 12-8: Использование выражения с тегом {{each}}