在Mustache中,如何获取当前Section的索引

chr*_*ton 55 templates mustache

我正在使用Mustache并使用数据

{ "names": [ {"name":"John"}, {"name":"Mary"} ] }
Run Code Online (Sandbox Code Playgroud)

我的小胡子模板是:

{{#names}}
    {{name}}
{{/names}}
Run Code Online (Sandbox Code Playgroud)

我想要做的是获得数组中当前数字的索引.就像是:

{{#names}}
    {{name}} is {{index}}
{{/names}}
Run Code Online (Sandbox Code Playgroud)

打印出来

John is 1
Mary is 2
Run Code Online (Sandbox Code Playgroud)

是否可以使用Mustache获得此功能?或使用把手或其他扩展?

dav*_*ave 48

这是我在JavaScript中的方式:

var idx = 0;

var data = { 
   "names": [ 
       {"name":"John"}, 
       {"name":"Mary"} 
    ],
    "idx": function() {
        return idx++;
    }
};

var html = Mustache.render(template, data);
Run Code Online (Sandbox Code Playgroud)

你的模板:

{{#names}}
    {{name}} is {{idx}}
{{/names}}
Run Code Online (Sandbox Code Playgroud)

  • 这个问题的一个问题是你必须记住只得到一次`idx`,否则它会改变当前对象.在我们的一些模板中,我们在当前对象的多个位置使用索引. (10认同)

Kim*_*Kim 31

作为参考,此功能现在内置于Handlebars,它与Mustache兼容.

使用 {{@index}}

{{#names}}
    {{name}} is {{@index}}
{{/names}}
Run Code Online (Sandbox Code Playgroud)

约翰是0

玛丽是1

  • 与小胡子兼容的把手是一种常见的误解.把手根本不兼容胡子.它们根本不可互换.只是想澄清一下,因为我被抓到试图用另一个. (22认同)
  • 这对我不起作用.它适合你吗? (11认同)
  • 只有小胡子有什么意思吗? (5认同)
  • 这不应该是接受的答案,因为它没有回答标题中的问题. (4认同)
  • 这是一个可怕的答案。Mustache 不是特定于平台的,而 Handlebars 是。 (2认同)

mat*_*tsh 13

在handlebars.js中,您可以使用辅助函数完成此操作.(事实上​​,这里提到的把手之一的优势之一http://yehudakatz.com/2010/09/09/announcing-handlebars-js/是你可以使用助手而不必在调用模板之前重写对象.

所以,你可以这样做:

  var nameIndex = 0;
  Handlebars.registerHelper('name_with_index', function() {
    nameIndex++;
    return this.name + " is " + nameIndex;
  })
Run Code Online (Sandbox Code Playgroud)

然后,您的模板可以是这样的:

{{#names}}
<li>{{name_with_index}}</li>
{{/names}}
Run Code Online (Sandbox Code Playgroud)

您的数据与以前相同,即:

{ "names": [ {"name":"John"}, {"name":"Mary"} ] };
Run Code Online (Sandbox Code Playgroud)

你得到这个输出:

<li>John is 1</li>
<li>Mary is 2</li>
Run Code Online (Sandbox Code Playgroud)

为了使其真正起作用,每次渲染模板时都需要重置nameIndex,因此为了做到这一点,你可以在列表的开头有一个重置助手.所以完整的代码看起来像这样:

  var data = { "names": [ {"name":"John"}, {"name":"Mary"} ] };
  var templateSource = "<ul>{{reset_index}}{{#names}}<li>{{name_with_index}}</li>{{/names}}</ul>";
  var template = Handlebars.compile(templateSource);

  var helpers = function() {
    var nameIndex = 0;
    Handlebars.registerHelper('name_with_index', function() {
      nameIndex++;
      return this.name + " is " + nameIndex;
    });
    Handlebars.registerHelper('reset_index', function() {
      nameIndex = 0;
    })
  }();

  var htmlResult= template(data);
  $('#target').html(htmlResult);

  var htmlResult2= template(data);
  $('#target2').html(htmlResult2);
Run Code Online (Sandbox Code Playgroud)

(这可以正确渲染模板两次.)


Chr*_*row 7

您可以在对象列表上运行以下循环.

该解决方案具有以下优点:

  • 不更改模型数据
  • 索引可以多次访问

码:

for( var i=0; i< the_list.length; i++) {
    the_list[i].idx = (function(in_i){return in_i+1;})(i);
}
Run Code Online (Sandbox Code Playgroud)

说明:

使用函数而不是变量名,因此数据不会发生变异.Closure用于在循环中创建函数时返回'i'的值,而不是在循环结束时返回i的值.


Pie*_*rre 6

对于Mustache,更好的方法是使用获取索引的函数indexOf:

var data = { 
   names: [ {"name":"John"}, {"name":"Mary"} ],
    index: function() {
        return data.names.indexOf(this);
    }
};

var html = Mustache.render(template, data);
Run Code Online (Sandbox Code Playgroud)

在您的模板中:

{{#names}}
    {{name}} is {{index}}
{{/names}}
Run Code Online (Sandbox Code Playgroud)

缺点是这个index函数有硬编码的数组data.names使它更动态,我们可以使用另一个这样的函数:

var data = { 
   names: [ {"name":"John"}, {"name":"Mary"} ],
    index: function() {
        return function(array, render) {
            return data[array].indexOf(this);
        }
    }
};

var html = Mustache.render(template, data);
Run Code Online (Sandbox Code Playgroud)

在模板中使用:

{{#names}}
    {{name}} is {{#index}}names{{/index}}
{{/names}}
Run Code Online (Sandbox Code Playgroud)

还有一个小的缺点是,你必须数组名传递给在这个例子中,索引函数names,{{#index}}names{{/index}}.

  • 另一个问题是这个算法是 O(N^2),这可能会导致中等大小的列表出现问题。每次获得一项的索引时,都必须搜索整个列表。 (2认同)