6

我有一个使用 Handlebars 模板输出的 json 对象数组;我目前正在使用 {{#each object}}...{{/each}}。我现在需要通过对象的一个​​属性对对象进行排序,这再次使用把手助手和咖啡脚本没有问题,但是,我的模板中有一个问题,因为我无法弄清楚如何使用每个来迭代排序的数组.

到目前为止,我的研究表明我可能需要编写一个自定义的 Handlebars 助手,它实际上是:

{{#each_with_sort array}}

我现有的排序助手是这样的

   Handlebars.registerHelper sort_me =>
     myArray.sort (a,b)->
       return if +a.sort_index >= +b.sort_index then 1 else -1

但是,我很难在模板中使用排序数组 - 例如,它并不像

 {{#each sort_me(myArray)}}

数据来自第三方 API,所以我必须在把手/咖啡脚本中执行排序。

4

2 回答 2

12

最简单的做法是在数据到达 Handlebars 之前对其进行排序,然后您可以{{#each ...}}照常使用,不需要任何帮助。这种方法在 Handlebars 中很常见,模板通常分为两部分:用于数据修改/重新排列的 (Java|Coffee) 脚本部分和模板本身。

顺便说一句,您需要调整比较器函数来表现属性。来自精美手册

如果compareFunction提供,则数组元素根据比较函数的返回值进行排序。如果ab是要比较的两个元素,则:

  • 如果compareFunction(a, b)小于 0,则排序a到比 低的索引b,即 a 优先。
  • 如果compareFunction(a, b)返回 0,则彼此保持不变ab但对所有不同元素进行排序。注意:ECMAscript 标准不保证这种行为,因此并非所有浏览器(例如,至少可以追溯到 2003 年的 Mozilla 版本)都尊重这一点。
  • 如果compareFunction(a, b)大于 0,则排序b到比 更低的索引a

0因此,如果a.sort_index和相同,您想返回b.sort_index,更像这样:

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/

于 2013-07-15T21:07:40.210 回答
0

我只是收集各种 javascript 函数并将其推送到把手,如下所示:

Handlebars.registerHelper({
    eq: (v1, v2) => v1 === v2,
    ne: (v1, v2) => v1 !== v2,
    lt: (v1, v2) => v1 < v2,
    gt: (v1, v2) => v1 > v2,
    lte: (v1, v2) => v1 <= v2,
    gte: (v1, v2) => v1 >= v2,    
    sort() {
        return arguments[0].sort();
    }
});

这样,我将其用作:

{{#each (sort students)}}
  <div> {{this}} </div>
{{/each}}

{{#if (eq arg1 arg2)}}
  <div> Delete </div>
{{/if}}

如果您需要许多功能,您可以将“if”功能和“每个”功能的助手分开......只是为了让它更有条理......

于 2021-06-03T15:36:58.523 回答