首页 文章

使用handlebars.js模板以数组中的最后一项为条件

提问于
浏览
59

我正在利用handlebars.js作为我的模板引擎,并且我希望只有当它是模板配置对象中包含的数组中的最后一项时才显示条件段 .

{
  columns: [{<obj>},{<obj>},{<obj>},{<obj>},{<obj>}]
}

我已经拉了一个助手来做一些相等/更大/更少的比较,并且已经成功识别出这样的初始项目但是没有运气来访问我的目标数组的长度 .

Handlebars.registerHelper('compare', function(lvalue, rvalue, options) {...})

"{{#each_with_index columns}}"+
"<div class='{{#equal index 0}} first{{/equal}}{{#equal index ../columns.length()}} last{{/equal}}'>"+
"</div>"+
"{{/each_with_index}}"

有没有人知道一个快捷方式,不同的方法,以及一些把手的优点,这将使我不必撕裂到handlebars.js引擎,以确定最佳的课程?

5 回答

  • 25

    如果您只是尝试处理数组的第一项,这可能会有所帮助

    {{#each data-source}}{{#if @index}},{{/if}}"{{this}}"{{/each}}

    @index由每个帮助程序提供,对于第一个项目,它将等于零,因此可以由if帮助程序处理 .

  • 150

    从Handlebars v1.1.0开始,您现在可以在每个帮助程序中使用@first和@last布尔值来解决此问题:

    {{#each foo}}
        <div class='{{#if @first}}first{{/if}}
                    {{#if @last}} last{{/if}}'>
          {{@key}} - {{@index}}
        </div>
    {{/each}}
    

    我写的一个快速帮手就是:

    Handlebars.registerHelper("foreach",function(arr,options) {
        if(options.inverse && !arr.length)
            return options.inverse(this);
    
        return arr.map(function(item,index) {
            item.$index = index;
            item.$first = index === 0;
            item.$last  = index === arr.length-1;
            return options.fn(item);
        }).join('');
    });
    

    然后你可以写:

    {{#foreach foo}}
        <div class='{{#if $first}} first{{/if}}{{#if $last}} last{{/if}}'></div>
    {{/foreach}}
    
  • 0

    从Handlebars 1.1.0开始,第一个和最后一个已成为每个助手的原生 . 见票#483 .

    用法类似于Eberanov's helper类:

    {{#each foo}}
        <div class='{{#if @first}}first{{/if}}{{#if @last}} last{{/if}}'>{{@key}} - {{@index}}</div>
    {{/each}}
    
  • 88

    解:

    <div class='{{#compare index 1}} first{{/compare}}{{#compare index total}} last{{/compare}}'></div>
    

    利用以下博客中的助手和主旨......

    https://gist.github.com/2889952

    http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates/

    // {{#each_with_index records}}
    //  <li class="legend_item{{index}}"><span></span>{{Name}}</li>
    // {{/each_with_index}}
    
    Handlebars.registerHelper("each_with_index", function(array, fn) {
      var total = array.length;
      var buffer = "";
    
      //Better performance: http://jsperf.com/for-vs-foreach/2
      for (var i = 0, j = total; i < j; i++) {
        var item = array[i];
    
        // stick an index property onto the item, starting with 1, may make configurable later
        item.index = i+1;
        item.total = total;
        // show the inside of the block
        buffer += fn(item);
      }
    
      // return the finished buffer
      return buffer;
    
    });
    
    Handlebars.registerHelper('compare', function(lvalue, rvalue, options) {
    
        if (arguments.length < 3)
            throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
    
        operator = options.hash.operator || "==";
    
        var operators = {
            '==':       function(l,r) { return l == r; },
            '===':      function(l,r) { return l === r; },
            '!=':       function(l,r) { return l != r; },
            '<':        function(l,r) { return l < r; },
            '>':        function(l,r) { return l > r; },
            '<=':       function(l,r) { return l <= r; },
            '>=':       function(l,r) { return l >= r; },
            'typeof':   function(l,r) { return typeof l == r; }
        }
    
        if (!operators[operator])
            throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator);
    
        var result = operators[operator](lvalue,rvalue);
    
        if( result ) {
            return options.fn(this);
        } else {
            return options.inverse(this);
        }
    
    });
    

    Notice the starting index is correctly 1.

  • 1

    我从Matt Brennan对helper做了一些改进,你可以将这个帮助器与对象或数组一起使用,这个解决方案需要Underscore库:

    Handlebars.registerHelper("foreach", function(context, options) {
      options = _.clone(options);
      options.data = _.extend({}, options.hash, options.data);
    
      if (options.inverse && !_.size(context)) {
        return options.inverse(this);
      }
    
      return _.map(context, function(item, index, list) {
        var intIndex = _.indexOf(_.values(list), item);
    
        options.data.key = index;
        options.data.index = intIndex;
        options.data.isFirst = intIndex === 0;
        options.data.isLast = intIndex === _.size(list) - 1;
    
        return options.fn(item, options);
      }).join('');
    });
    

    用法:

    {{#foreach foo}}
        <div class='{{#if @first}}first{{/if}}{{#if @last}} last{{/if}}'>{{@key}} - {{@index}}</div>
    {{/foreach}}
    

相关问题