In Mustache, How to get the index of the current Section

前端 未结 13 1056
臣服心动
臣服心动 2020-12-13 03:52

I am using Mustache and using the data

{ \"names\": [ {\"name\":\"John\"}, {\"name\":\"Mary\"} ] }

My mustache template is:



        
相关标签:
13条回答
  • 2020-12-13 04:18

    For reference, this functionality is now built in to Handlebars which has compatibility with Mustache.

    Use {{@index}}

    {{#names}}
        {{name}} is {{@index}}
    {{/names}}
    

    John is 0

    Mary is 1

    0 讨论(0)
  • 2020-12-13 04:19

    This is how I do it in JavaScript:

    var idx = 0;
    
    var data = { 
       "names": [ 
           {"name":"John"}, 
           {"name":"Mary"} 
        ],
        "idx": function() {
            return idx++;
        }
    };
    
    var html = Mustache.render(template, data);
    

    Your template:

    {{#names}}
        {{name}} is {{idx}}
    {{/names}}
    
    0 讨论(0)
  • 2020-12-13 04:20

    If you can control the output of the JSON string, then try this out.

    { "names": [ {"name":"John", "index":"1"}, {"name":"Mary", "index":"2"} ] }
    

    So when you make your JSON string, add the index as another property for each object.

    0 讨论(0)
  • 2020-12-13 04:20
    <script>var index = 1;</script>
    {{#names}}
        {{name}} is <script>document.write(index++);</script>
    {{/names}}
    

    This works perfectly fine.

    0 讨论(0)
  • 2020-12-13 04:21

    In handlebars.js you can accomplish this with a helper function. (In fact, one of the advantages mentioned about handlebars here http://yehudakatz.com/2010/09/09/announcing-handlebars-js/ is that you can use helpers instead of having to rewrite the objects before calling the template.

    So, you could do this:

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

    And, then your template can be this:

    {{#names}}
    <li>{{name_with_index}}</li>
    {{/names}}
    

    Your data is the same as before, i.e.:

    { "names": [ {"name":"John"}, {"name":"Mary"} ] };
    

    And you get this output:

    <li>John is 1</li>
    <li>Mary is 2</li>
    

    To make this really work, nameIndex needs to get reset each time the template is rendered, so to do that you can have a reset helper at the beginning of the list. So full code looks like this:

      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);
    

    (This can correctly render the template twice.)

    0 讨论(0)
  • 2020-12-13 04:21

    You can run the following loop on your list of objects.

    This solution has the following advantages:

    • Does not change the model data
    • The index can be accessed multiple times

    Code:

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

    Explanation:

    A function is used instead of a variable name, so the data is not mutated. Closure is used to return the value of 'i' at the time the function is created in the loop instead of the value of i at the end of the loop.

    0 讨论(0)
提交回复
热议问题