javascript - Handlebars : sorting a list while keeping the original sort index

标签 javascript sorting handlebars.js helper

Demo

我想显示一个已排序的列表,同时还需要知道原始排序索引 (org_index)。

如何做到这一点?我应该在 .registerHelper('eachSort') 的数组 sorted 中注入(inject)一个新字段,例如:[{'name':'b', 'org_index ':0},...

<小时/>

JS

Handlebars.registerHelper('eachSort', function(array, key, opts) {
  // requires: underscore
  var sorted = _.sortBy(array, function(item) {
    return item[key]
  });
  return Handlebars.helpers.each(sorted, opts);
});


var arr = [{'name':'b'}, {'name':'c'}, {'name':' a'}];
<小时/>

模板

<script type="text/x-handlebars-template" id="tpl-eachSort">
   {{#eachSort . 'name'}}
       name={{name}}=  / index_now={{@index}}= / index_org=?{{org_index}}= <br/>
   {{/eachSort}}        
</script>
<小时/>

结果

name= a= / index_now=0= / index_org=?= 
name=b= / index_now=1= / index_org=?= 
name=c= / index_now=2= / index_org=?= 

最佳答案

如果您希望重用默认的 each 帮助器,并且由于无法向其中注入(inject)某些功能,您可以按照您的建议将原始索引嵌入到项目本身中。虽然最简单,但将帮助器元数据直接附加到数据中并不是很干净。

helper

handlebars.registerHelper('eachSort', function(array, key, opts) {
    // append metadata into data
    for (var i = 0; i < array.length; i++) {
        array[i].originalIndex = i
    }
    // sort
    var sorted = _.sortBy(array, function(item) {
        return item[key]
    })
    // default each
    return handlebars.helpers.each(sorted, opts)
})

模板

{{#eachSort . 'name'}}
name={{name}}=  / index_now={{@index}}= / index_org={{originalIndex}}= <br/>
{{/eachSort}}

正确的方法是使用 @data 变量来实现此目的。您可以跳过默认的 each 帮助器并手动滚动它,非常简单。

helper

handlebars.registerHelper('eachSort', function(array, key, opts) {
    // zip for sorting
    var zipped = []
    for (var i = 0; i < array.length; i++) {
        zipped.push({
            originalData: array[i],
            originalIndex: i
        })
    }
    // sort
    var sorted = _.sortBy(zipped, function(item) {
        return item.originalData[key]
    })
    // custom each
    var result = ''
    for (var i = 0; i < sorted.length; i++) {
        var item = sorted[i]
        // set metadata as @data variables
        opts.data.index = i
        opts.data.originalIndex = item.originalIndex
        result += opts.fn(item.originalData, opts)
    }
    return result
})

模板

{{#eachSort . 'name'}}
name={{name}}=  / index_now={{@index}}= / index_org={{@originalIndex}}= <br/>
{{/eachSort}}

或者您可以更多地参与并使用 @data 变量和默认的 each 帮助器。由于可以使用函数作为 @data 变量,因此您可以将 @originalIndex 数据变量注册为生成器,该生成器每次都会按排序顺序一一返回原始索引它的名字是:

handlebars.registerHelper('eachSort', function(array, key, opts) {
    // zip for sorting
    var zipped = []
    for (var i = 0; i < array.length; i++) {
        zipped.push({
            originalData: array[i],
            originalIndex: i
        })
    }
    // sort
    var sorted = _.sortBy(zipped, function(item) {
        return item.originalData[key]
    })
    // separate sorted data
    var originalData = []
    var originalIndex = []
    for (var i = 0; i < sorted.length; i++) {
        var item = sorted[i]
        originalData.push(item.originalData)
        originalIndex.push(item.originalIndex)
    }
    // set original index metadata generator as @data variable
    opts.data.originalIndex = function() {
        return originalIndex.shift()
    }
    // default each
    return handlebars.helpers.each(originalData, opts)
})

关于javascript - Handlebars : sorting a list while keeping the original sort index,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27644884/

相关文章:

javascript - 输入文本框为正数/负数/ float ,最大长度为 11

javascript - google.script.run独立使用

javascript - 单击一次即可按升序和降序对对象数组进行排序

javascript - 打包基于 Handlebars 的小部件 : javascript and html

javascript - 在跨子域服务器端和 JavaScript 上设置/删除 Cookie

javascript - Google 电子表格脚本 "Cell reference out of range"

javascript - 如何在 JavaScript 中对带有主节点文本的 json 对象进行排序?

Java 对两个整数数组进行排序

handlebars.js - 如何使用 Handlebars.js 在索引处获取数组值?

node.js - 每个输出超过记录的 Handlebars