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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11479094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:59:55  来源:igfitidea点击:

conditional on last item in array using handlebars.js template

javascriptarrayshelpershandlebars.jstemplating

提问by techie.brandon

I am leveraging handlebars.js for my templating engine and am looking to make a conditional segment display only if it is the last item in array contained in the templates configuration object.

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

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

I've already pulled in a helper to do some equality/greater/less-than comparisons and have had success identifying the initial item this way but have had no luck accessing my target array's length.

我已经引入了一个助手来进行一些相等/大于/小于比较,并且已经成功地以这种方式识别了初始项目,但没有运气访问我的目标数组的长度。

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}}"

Does anyone know a shortcut, different approach, and some handlebars goodness that will keep me from having to tear into the handlebars.js engine to determine best course?

有谁知道捷径、不同的方法和一些把手的优点,可以让我不必撕开handlebars.js 引擎来确定最佳路线?

回答by Jacob van Lingen

Since Handlebars 1.1.0, first and last has become native to the each helper. See ticket #483.

从 Handlebars 1.1.0 开始, first 和 last 已成为每个助手的本机。见票#483

The usage is like Eberanov'shelper class:

用法类似于Eberanov 的辅助类:

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

回答by Kara Brightwell

As of Handlebars v1.1.0, you can now use the @firstand @lastbooleans in the each helper for this problem:

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

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


A quick helper I wrote to do the trick is:

我写的一个快速帮手是:

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('');
});

Then you can write:

然后你可以写:

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

回答by Yong Qu

If you just try to handle the first item of the array, this may help

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

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

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

@index is provided by the each helper and for the first item, it would be equal to zero and thus can be handled by the if helper.

@index 由 each helper 提供,对于第一项,它将等于 0,因此可以由 if helper 处理。

回答by techie.brandon

Solution:

解决方案:

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

Leveraging helpers from the following blog and gist...

利用以下博客和要点中的帮助程序...

https://gist.github.com/2889952

https://gist.github.com/2889952

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

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。

回答by ebaranov

I made a little improvements in helper from Matt Brennan, you can use this helper with Objects or Arrays, this solution required Underscorelibrary:

我对Matt Brennan 的helper 做了一些改进,您可以将此 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('');
});

Usage:

用法:

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