62 votes

Dans Mustache, Comment obtenir l'index de la section courante ?

J'utilise Moustache et en utilisant les données

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

Mon modèle de moustache est :

{{#names}}
    {{name}}
{{/names}}

Ce que je veux pouvoir faire, c'est obtenir un index du numéro actuel dans le tableau. Quelque chose comme :

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

et le faire imprimer

John is 1
Mary is 2

Est-il possible d'obtenir cela avec Mustache ? ou avec Handlebars ou une autre extension ?

0 votes

Fonctionne en temps O(n)... Mustache.render('{{#list}}{{index}}{{/list}}', { list: ['a', 'b', 'c' ], index: () => (++this.i || (this.i = 0)) });

51voto

dave Points 1433

Voici comment je le fais en JavaScript :

var idx = 0;

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

var html = Mustache.render(template, data);

Votre modèle :

{{#names}}
    {{name}} is {{idx}}
{{/names}}

10 votes

Le problème, c'est qu'il faut se rappeler de ne prendre que le idx une fois, sinon elle sera modifiée pour l'objet actuel. Dans certains de nos modèles, nous utilisons l'indice à plus d'un endroit pour l'objet courant.

0 votes

Excellente réponse et j'ai ajouté une solution pour les {{idx}} multiples.

0 votes

La solution pour multiple {{index}} peuvent être trouvés sur Index d'un élément de tableau dans Mustache.js @oyatek

31voto

Kim Points 709

Pour référence, cette fonctionnalité est maintenant intégrée à Handlebars qui est compatible avec Mustache.

Utilisez {{@index}}

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

John est 0

Mary est 1

0 votes

Yay ! Enfin, bien que pour les projets que nous avons fini par utiliser, le code utilise les bibliothèques natives Android et objc mustache. Nous ne pouvons donc plus utiliser le JavaScript Handlebars. Mais cela semble être une excellente alternative maintenant.

29 votes

La compatibilité du guidon avec la moustache est une idée fausse très répandue. Le guidon n'est PAS du tout compatible avec la moustache. Ils ne sont pas du tout interchangeables. Je voulais juste clarifier ce point car je me suis fait prendre en essayant d'utiliser l'un pour l'autre.

6 votes

Y a-t-il un moyen de le faire avec seulement la moustache ?

12voto

mattsh Points 1166

Dans handlebars.js, vous pouvez accomplir cela avec une fonction d'aide. (En fait, l'un des avantages mentionnés à propos de handlebars ici http://yehudakatz.com/2010/09/09/announcing-handlebars-js/ est que vous pouvez utiliser des aides au lieu de devoir réécrire les objets avant d'appeler le modèle.

Donc, tu pourrais faire ça :

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

Et, ensuite, votre modèle peut être celui-ci :

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

Vos données sont les mêmes que précédemment, à savoir :

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

Et vous obtenez ce résultat :

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

Pour que cela fonctionne vraiment, nameIndex doit être réinitialisé à chaque fois que le modèle est rendu, donc pour ce faire, vous pouvez avoir une aide de réinitialisation au début de la liste. Le code complet ressemble donc à ceci :

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

(Cela peut rendre correctement le modèle deux fois).

0 votes

Cela pourrait fonctionner, mais le problème est que vous ne pouvez pas utiliser l'index à plus d'un endroit dans l'article. En effet, à chaque fois que vous récupérez l'index, vous l'incrémentez. Cela ne fonctionne pas bien pour les concepteurs de modèles et causera des bogues et des problèmes. De plus, le fait d'avoir "reset_index" ajoute une méthode logique pour réinitialiser l'index, ce qui, je crois, va à nouveau dans le sens des modèles sans logique. J'ai vu que dans la version Android, il y a un {{-index}} qui fait la bonne chose.

7voto

Chris Dutrow Points 8662

Vous pouvez exécuter la boucle suivante sur votre liste d'objets.

Cette solution présente les avantages suivants :

  • Ne modifie pas les données du modèle
  • L'index peut être consulté plusieurs fois

Code :

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

Explication :

Une fonction est utilisée au lieu d'un nom de variable, de sorte que les données ne sont pas mutées. La fermeture est utilisée pour renvoyer la valeur de 'i' au moment où la fonction est créée dans la boucle au lieu de la valeur de i à la fin de la boucle.

4voto

lukemh Points 841

Une aide précieuse ici :

// {{#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 buffer = "";
    for (var i = 0, j = array.length; 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;

        // show the inside of the block
        buffer += fn(item);
    }

    // return the finished buffer
    return buffer;

});

Source : https://gist.github.com/1048968

1 votes

Merci, celui-ci a fonctionné mais je l'ai étendu un peu pour mon cas d'utilisation. gist.github.com/1429324

0 votes

Merci. mise en œuvre simple d'une propriété d'indexation expando. je l'utilise.

0 votes

GRMustache (Mustache for objective-C) peut également faire face à cette situation : github.com/groue/GRMustache/blob/master/Guides/sample_code/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X