Pen block helper: each with sorting

I have an array of json objects that are output using the Handlebars pattern; I am currently using {{#each object}} ... {{/ each}}. Now I need to sort the objects according to one of the properties of the object, which again is not a problem using the handlebars and coffeescript helper, however, I have a problem in my template, since I cannot decide how to iterate over the sorted array using each.

My research so far shows that I probably need to write a special Handlebars helper, which will, in fact, be:

{{#each_with_sort array}} 

My existing sorting 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'm struggling to use a sorted array in a template - for example, it's not as simple as

  {{#each sort_me(myArray)}} 

The data comes from a third-party API, so I have to sort in handlebars / coffeescript.

+4
source share
1 answer

The easiest way would be to sort the data before it {{#each ...}} into the Handlebars, then you can use {{#each ...}} as usual, and no helpers are needed. This approach is quite common with Handlebars, the template is often divided into two parts: a piece of (Java | Coffee) Script for processing / rearranging data and the template itself.

As an aside, you want to set your comparator function to the behavior of the property. From the excellent guide :

If compareFunction supplied, the elements of the array are sorted according to the return value of the comparison function. If a and b compare two elements, then:

  • If compareFunction(a, b) less than 0, sort a with a lower index than b , i.e. at the first place.
  • If compareFunction(a, b) returns 0, leave a and b unchanged relative to each other, but sorted by all the different elements. Note. The ECMAscript standard does not guarantee this behavior, and therefore not all browsers (for example, versions of Mozilla dated at least 2003) respect this.
  • If compareFunction(a, b) greater than 0, sort b with a lower index than a .

So you want to return 0 if a.sort_index and b.sort_index same, something 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 

If you need to perform sorting inside the template, you need to add a special each_with_sort helper for sorting and iteration, for example:

 # 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 will look like this:

 {{#each_with_sort array "sort_index"}} ... {{/each_with_sort}} 

Demo: http://jsfiddle.net/ambiguous/zusq2tt4/

+9
source

Source: https://habr.com/ru/post/1491499/


All Articles