Handlebars.js пользовательская функция сортировки
Я использую Handlebars для отображения комментариев.
{{#each COMMENTS}}
<div class="heightfix">
<div class="commentIcon"></div>
<label id="commentDate1" class="bold">{{COMMENTON}}</label>:
<label id="commentCreator1" class="bold">{{COMMENTBY_FIRSTNAME}} {{COMMENTBY_LASTNAME}}</label>
<label class="commentContent" id="commenttext_{{ID}}">{{COMMENTTEXT}}</label>
</div>
{{/each}}
В этих комментариях у меня есть ИНДЕКС. Я хотел бы отображать комментарии в соответствии с их индексом. Комментарий 0 Комментарий 1 Комментарий 2 Комментарий 3 .....
Как мне добиться этого с помощью пользовательских функций? Спасибо
2 ответа
Метод 1: Пользовательский Accessor
Если у вас есть контроль над контекстом (и вы, вероятно, делаете), вы можете реализовать это с помощью методов доступа к свойствам. Допустим, ваш контекст содержит комментарии в беспорядочном порядке:
var context = {
comments: [
{ idx:6, text:'violet' },
{ idx:1, text:'orange' },
{ idx:0, text:'red' },
{ idx:5, text:'indigo' },
{ idx:3, text:'green' },
{ idx:2, text:'yellow' },
{ idx:4, text:'blue' },
],
};
Вы могли бы просто отсортировать comments
массив перед размещением шаблона (обратите внимание, что для числовых значений вы можете просто вычесть их, чтобы получить естественное упорядочение):
context.comments.sort( function(a,b) { return a.idx - b.idx; } );
Проблема в том, что изменит объект контекста, чего вы, возможно, не захотите делать. Решение состоит в том, чтобы предоставить пользовательский метод доступа, который будет возвращать комментарии, отсортированные по некоторому пользовательскому свойству. Вот как мы можем это сделать:
Object.defineProperty( context, 'commentsByIdx', {
get: function() {
// note that we call concat() to create a copy of
// the array; otherwise we are modifying the
// the original array, which is a side effect
return this.comments.concat()
.sort( function(a,b) { return a.idx - b.idx } );
}
});
Вы можете увидеть это решение в действии здесь: http://jsfiddle.net/Jammerwoch/ShZLY/
Способ 2: Помощник блока руля
Другой подход заключается в реализации вспомогательного блока Handlebars. Этот подход будет работать лучше, если у вас нет большого контроля над контекстом (или вы не хотите загрязнять его пользовательскими свойствами). Просто зарегистрируйте помощника Handlebars:
Handlebars.registerHelper('eachByIdx', function(context,options){
var output = '';
var contextSorted = context.concat()
.sort( function(a,b) { return a.idx - b.idx } );
for(var i=0, j=contextSorted.length; i<j; i++) {
output += options.fn(contextSorted[i]);
}
return output;
});
И назовите это так в вашем шаблоне:
{{#eachByIdx comments}}
<li>{{text}}</li>
{{/eachByIdx}}
Смотрите это в действии здесь: http://jsfiddle.net/Jammerwoch/aeCYg/1/
В целом, я считаю, что первый метод предпочтительнее, так как он создает новое представление о ваших данных, которое потенциально полезно вне Handlebars. Кроме того, для обычного читателя кода Handlebars это будет иметь больше смысла.
Ниже я сортирую элементы для галереи изображений
Надо знать
- Функция занимает 3 периметра
- данные для сортировки
- значение для сортировки
- заголовок отсортированных данных
- Функция возвращает HTML с отсортированными данными
Данные
{
"imageUrl" : "img/shoes.jpg",
"category" : "shoes"
},
{
"imageUrl" : "img/hat.jpg",
"category" : "hat"
}
Функция сортировки узла JS на стороне сервера
"use strict";
var helpers = module.exports;
helpers.sort = function(data, value, heading) {
var str = '<div class="row">'+
'<div class="container headings">'+
'<h2 class="center">'+heading+'</h2>'+ // heading data from Markdown
'<hr>'+
'</div>'+
'<div class="swap"><i class="material-icons">swap_horiz</i></div>'+
'<div class="carousel">';
data.forEach(function(gal){ // loop through all data
if (gal.category === value) { // sort data by value
str += '<a class="carousel-item" href="#!"><img src="'+gal.imageUrl+'" alt="gallery_image"></a>'; // gallery item
}
})
str += '</div>'+
'</div>'+
'</div>';
return str; // return sorted html data
};
Разметка руля на стороне клиента
{{#sort data 'shoes' 'Jordans'}}{{/sort}}
- вызовите помощника и добавьте 3 параметра
- 1-й параметр включает в себя все данные для сортировки
data
- 2-й параметр - это значение для сортировки
'shoes'
- 3-й параметр - заголовок отсортированных данных
'Jordans'
- 1-й параметр включает в себя все данные для сортировки