最简单的做法是在数据到达 Handlebars 之前对其进行排序,然后您可以像往常一样使用{{#each ...}},并且不需要任何助手。这种方法在 Handlebars 中很常见,模板通常分为两部分:用于数据修改/重新排列的 (Java|Coffee)Script 部分和模板本身。
顺便说一句,您需要调整比较器函数以使其具有行为属性。来自fine manual:
如果提供了compareFunction,则数组元素根据比较函数的返回值进行排序。如果a 和b 是被比较的两个元素,那么:
- 如果
compareFunction(a, b) 小于0,则将a 排序到比b 低的索引,即a 排在第一位。
- 如果
compareFunction(a, b) 返回0,则保持a 和b 彼此保持不变,但对所有不同元素进行排序。注意:ECMAscript 标准不保证这种行为,因此并非所有浏览器(例如至少可以追溯到 2003 年的 Mozilla 版本)都尊重这一点。
- 如果
compareFunction(a, b) 大于0,则将b 排序到低于a 的索引。
所以如果a.sort_index 和b.sort_index 相同,您想返回0,更像这样:
myArray.sort (a,b)->
a = +a.sort_index
b = +b.sort_index
return 1 if a > b
return 0 if a == b
return -1 if a < b
如果您必须在模板内进行排序,那么您需要添加一个自定义的 each_with_sort 助手来进行排序和迭代,如下所示:
# If you're always sorting by sort_index then you don't need the key argument
# and you might want to put the '+'-casting back in.
Handlebars.registerHelper('each_with_sort', (array, key, opts) ->
data = Handlebars.createFrame(opts.data) if(opts.data)
array = array.sort (a, b) ->
a = a[key]
b = b[key]
return 1 if a > b
return 0 if a == b
return -1 if a < b
s = ''
for e, i in array
data.index = i if(data) # Support the usual @index.
s += opts.fn(e, data: data)
s
)
你的模板会是这样的:
{{#each_with_sort array "sort_index"}}
...
{{/each_with_sort}}
演示:http://jsfiddle.net/ambiguous/zusq2tt4/