javascript - Handlebars.js 自定义函数排序

标签 javascript

我正在使用 Handlebars 来显示评论。

{{#each COMMENTS}}
     <div class="heightfix">
          <div class="commentIcon"></div>&nbsp;&nbsp;
             <label id="commentDate1" class="bold">{{COMMENTON}}</label>:&nbsp;
             <label id="commentCreator1" class="bold">{{COMMENTBY_FIRSTNAME}} {{COMMENTBY_LASTNAME}}</label>&nbsp;&nbsp;
             <label class="commentContent" id="commenttext_{{ID}}">{{COMMENTTEXT}}</label>
     </div>                                  
{{/each}}   

在那些评论中,我有索引。我想根据他们的索引显示评论。 评论 0 评论 1 评论 2 评论 3 ......

如何使用自定义函数实现此目的? 谢谢

最佳答案

方法一:自定义访问器

如果您可以控制上下文(您可能会这样做),则可以使用属性访问器来实现它。假设您的上下文包含乱序的评论:

var context = {
    comments: [
        { idx:6, text:'violet' },
        { idx:1, text:'orange' },
        { idx:0, text:'red' },
        { idx:5, text:'indigo' },
        { idx:3, text:'green' },
        { idx:2, text:'yellow' },
        { idx:4, text:'blue' },
    ],
};

您可以在呈现模板之前就地对 comments 数组进行排序(请注意,对于数值,您可以将它们相减以获得自然排序):

context.comments.sort( function(a,b) { return a.idx - b.idx; } );

问题在于它会修改上下文对象,而您可能不想这样做。一种解决方案是提供一个自定义访问器,它将返回按某些自定义属性排序的评论。以下是我们如何做到这一点:

Object.defineProperty( context, 'commentsByIdx', {
    get: function() {
        // note that we call concat() to create a copy of
        // the array; otherwise we are modifying the
        // the original array, which is a side effect
        return this.comments.concat()
            .sort( function(a,b) { return a.idx - b.idx } );
    }
});

您可以在此处查看此解决方案的实际应用:http://jsfiddle.net/Jammerwoch/ShZLY/

方法 2:Handlebars Block Helper

另一种方法是实现 Handlebars block helper .如果您对上下文没有太多控制权(或者不想用自定义属性污染它),这种方法会更好地工作。只需注册一个 Handlebars 助手:

Handlebars.registerHelper('eachByIdx', function(context,options){
    var output = '';
    var contextSorted = context.concat()
        .sort( function(a,b) { return a.idx - b.idx } );
    for(var i=0, j=contextSorted.length; i<j; i++) {
        output += options.fn(contextSorted[i]);
    }
    return output;
});

然后在你的模板中这样调用它:

{{#eachByIdx comments}}
    <li>{{text}}</li>
{{/eachByIdx}}

在此处查看实际效果:http://jsfiddle.net/Jammerwoch/aeCYg/1/

总而言之,我发现第一种方法更可取,因为它创建了一个新的数据 View ,可能在 Handlebars 之外有用。此外,对于 Handlebars 代码的普通读者来说,它会更有意义。

关于javascript - Handlebars.js 自定义函数排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17934207/

相关文章:

javascript - 选中复选框时使用 JavaScript 访问 CSS 样式

javascript - 图没有占用 d3.js 中的整个空间

php - 将 JSON 对象附加到 URL 末尾

javascript - document.getElementById ("").style.display ='none' ;不管用

php - 检查数组javascript中的变量

javascript - 如何在 JavaScript 中以本地 let 方式销毁所有属性

javascript/jquery - 用户关闭浏览器时的跨浏览器检测?

javascript - 图像边距不变。可能是由于我的 javascript?

javascript - 如何避免 webGL 着色器加载对 cpu 施加过多负载

javascript - 使用 javascript 在 Mapbox 上使用加载的 geojson 生成器