车把帮助器:每个都有分类 [英] Handlebars Block Helper : each with sort
问题描述
我有一个使用Handlebars模板输出的json对象数组;我目前正在使用{{#each object}} ... {{/each}}.现在,我需要按对象的属性之一对对象进行排序,再次使用车把帮助器& coffeescript,但是,我的模板中存在一个问题,即我无法解决如何使用每个模板遍历已排序数组的问题.
I have an array of json objects which I output using a Handlebars template; I am currently doing using {{#each object}}...{{/each}}. I now need to sort the objects by one of the object's properties, which again is no problem using a handlebars helper & coffeescript, however, I have a problem in my template in that I cannot work out how to iterate over the sorted array using each.
到目前为止,我的研究表明我可能需要编写一个自定义的Handlebars帮助程序,该帮助程序实际上是:
My research so far indicates that I probably need to write a custom Handlebars helper which will, in effect, be:
{{#each_with_sort array}}
我现有的排序助手就是这样
My existing sort helper is like this
Handlebars.registerHelper sort_me =>
myArray.sort (a,b)->
return if +a.sort_index >= +b.sort_index then 1 else -1
但是,我正在努力使用模板中的排序数组-例如,它不像
but, I am struggling to be able to use the sorted array in the template - for example, it is not as simple as
{{#each sort_me(myArray)}}
数据来自第三方API,因此我必须在把手/咖啡脚本中进行排序.
The data is coming from a third party API, so I have to perform sorting in handlebars/coffeescript.
推荐答案
最简单的方法是在数据到达Handlebars之前对其进行排序,然后您可以照常使用{{#each ...}}
,而无需帮助程序.这种方法在Handlebars中很常见,模板通常分为两部分:一个用于数据处理/重新安排的(Java | Coffee)脚本部分和适当的模板.
The easiest thing to do would be to sort the data before it gets to Handlebars, then you can use {{#each ...}}
as usual and no helpers are needed. This sort of approach is quite common with Handlebars, the template is often split into two pieces: a (Java|Coffee)Script piece for data mangling/rearrangement and the template proper.
顺便说一句,您将需要调整比较器函数的行为属性.从精细手册:>
As an aside, you'll want to adjust your comparator function to behave property. From the fine manual:
如果提供了
compareFunction
,则根据比较函数的返回值对数组元素进行排序.如果a
和b
是要比较的两个元素,则:
If
compareFunction
is supplied, the array elements are sorted according to the return value of the compare function. Ifa
andb
are two elements being compared, then:
- 如果
compareFunction(a, b)
小于0,则将a
排序为比b
低的索引,即a排在第一位. - 如果
compareFunction(a, b)
返回0,则将a
和b
彼此保持不变,但对所有不同元素进行排序.注意:ECMAscript标准不能保证此行为,因此并非所有浏览器(例如,至少可追溯到2003年的Mozilla版本)都遵守此规定. - 如果
compareFunction(a, b)
大于0,则将b
排序为比a
低的索引.
- If
compareFunction(a, b)
is less than 0, sorta
to a lower index thanb
, i.e. a comes first. - If
compareFunction(a, b)
returns 0, leavea
andb
unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this. - If
compareFunction(a, b)
is greater than 0, sortb
to a lower index thana
.
因此,如果a.sort_index
和b.sort_index
相同,则要返回0
,类似这样:
So you want to return 0
if a.sort_index
and b.sort_index
are the same, something more like this:
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 must do the sorting inside the template then you'd need to add a custom each_with_sort
helper to do both the sorting and the iteration, something like this:
# 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
)
,您的模板将如下所示:
and your template would be like this:
{{#each_with_sort array "sort_index"}}
...
{{/each_with_sort}}
演示: http://jsfiddle.net/ambiguous/zusq2tt4/
这篇关于车把帮助器:每个都有分类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!