web-dev-qa-db-fra.com

Dans Mustache templating, existe-t-il un moyen élégant d’exprimer une liste séparée par des virgules sans la virgule finale?

J'utilise la bibliothèque de modèles Mustache et j'essaie de générer une liste séparée par des virgules sans virgule de fin, par exemple.

rouge, vert, bleu

Créer une liste avec la virgule de fin est simple, vu la structure

{
  "items": [
    {"name": "red"},
    {"name": "green"},
    {"name": "blue"}
  ]
}

et le gabarit

{{#items}}{{name}}, {{/items}}

cela résoudra à

rouge, vert, bleu, 

Cependant, je ne vois pas de façon élégante d’exprimer le cas sans la virgule. Je peux toujours générer la liste en code avant de la transférer dans le modèle, mais je me demandais si la bibliothèque offrait une approche alternative, telle que vous permettant de détecter s'il s'agissait du dernier élément de la liste du modèle.

71
John Kane

Hmm, douteux, la démo moustache montre assez, avec la propriété first, que vous devez avoir la logique dans les données JSON pour déterminer quand mettre la virgule.

Donc, vos données ressemblent à quelque chose comme:

{
  "items": [
    {"name": "red", "comma": true},
    {"name": "green", "comma": true},
    {"name": "blue"}
  ]
}

et votre modèle

{{#items}}
    {{name}}{{#comma}},{{/comma}}
{{/items}}

Je sais que ce n'est pas élégant, mais comme mentionné par d'autres Moustache est très léger et ne fournit pas de telles fonctionnalités.

38
Luca Matteis

Je pense qu'un meilleur moyen est de changer le modèle de manière dynamique. Par exemple, si vous utilisez JavaScript:

model['items'][ model['items'].length - 1 ].last = true;

et dans votre modèle, utilisez la section inversée: 

{{#items}}
    {{name}}{{^last}}, {{/last}}
{{/items}}

pour rendre cette virgule. 

85
Clyde

Trichez et utilisez CSS.

Si votre modèle est:

{
  "items": [
    {"name": "red"},
    {"name": "green"},
    {"name": "blue"}
  ]
}

alors faites votre modèle

<div id="someContainer">
{{#items}}
    <span>{{name}}<span>
{{/items}}
</div>

et ajouter un peu de CSS

#someContainer span:not(:last-of-type)::after {
  content: ", "    
}

J'imagine que quelqu'un dira que c'est un mauvais cas de mettre du balisage dans la présentation, mais je ne le pense pas. Les valeurs de séparation par des virgules sont une décision de présentation visant à faciliter l'interprétation des données sous-jacentes. C'est similaire à alterner la couleur de la police sur les entrées.

37
Jared

Si vous utilisez jmustache , vous pouvez utiliser les variables spéciales -first ou -last:

{{#items}}{{name}}{{^-last}}, {{/-last}}{{/items}}
22
dbort

On a répondu à la question de savoir si Moustache offre un moyen élégant de le faire, mais je me suis dit que le moyen le plus élégant de le faire serait peut-être d'utiliser CSS plutôt que de changer de modèle.

Modèle:

<ul class="csl">{{#items}}<li>{{name}}</li>{{/items}}</ul>

CSS: 

.csl li
{
    display: inline;
}
.csl li:before
{
    content: ", "
}
.csl li:first-child:before
{
    content: ""
}

Cela fonctionne dans IE8 + et d'autres navigateurs modernes.

6
David Hammond

Il n’existe pas de méthode intégrée à cela dans Moustache. Vous devez modifier votre modèle pour le prendre en charge. 

Une façon d'implémenter cela dans le modèle consiste à utiliser la balise de sélection inversée {{^last}} {{/last}}. Il omettra uniquement le texte pour l'élémentdernierde la liste. 

{{#items}}
    {{name}}{{^last}}, {{/last}}
{{/items}}

Ou vous pouvez ajouter à l'objet une chaîne de délimitation sous la forme ", ", ou idéalement la classe de base si vous utilisez un langage à héritage, puis définissez "délimiteur" sur une chaîne vide " " pour le dernier élément, comme ceci:

{{#items}}
    {{name}}{{delimiter}}
{{/items}}
5
cosbor11

Je ne peux pas penser à beaucoup de situations où vous voudriez lister un nombre inconnu d'éléments en dehors d'un <ul> ou d'un <ol>, mais voici comment vous procéderiez:

<p>
    Comma separated list, in sentence form;
    {{#each test}}{{#if @index}}, {{/if}}{{.}}{{/each}};
    sentence continued.
</p>

…produira:

Command separated list, in sentence form; asdf1, asdf2, asdf3; sentence continued.

Ceci est le guidon, remarquez. @index fonctionnera si test est un tableau.

5
Steven Vachon

Comme la question est:

existe-t-il un moyen élégant d’exprimer une liste séparée par des virgules sans virgule finale?

Changer les données - lorsque le dernier élément est déjà implicite, c'est-à-dire le dernier élément du tableau - n'est pas élégant.

Tout langage de modèle de moustache ayant des index de tableau peut le faire correctement. c'est à dire. sans rien ajouter aux données . Cela inclut le guidon, le fichier ractive.js et d’autres implémentations populaires de moustache.

{{# names:index}}
    {{ . }}{{ #if index < names.length - 1 }}, {{ /if }}
{{ / }}
2
mikemaccana

Comme Moustache se trouve sur le guidon, pourquoi ne pas utiliser une variable @data? J'ai trouvé cela l'option la plus propre:

{{#if @last}}, {{/if}}

Plus d'infos: http://handlebarsjs.com/reference.html#data

1
Roberto14

Intéressant. Je sais que c'est un peu paresseux, mais je règle généralement ce problème en utilisant des modèles dans la valorisation, plutôt que d'essayer de délimiter les valeurs par une virgule.

var global.items = {};
{{#items}}
    global.items.{{item_name}} = {{item_value}};
{{/items}}
0
Iwnnay

Si vous utilisez Java, vous pouvez utiliser les éléments suivants: 

https://github.com/spullara/mustache.Java/blob/master/compiler/src/test/Java/com/github/mustachejava/util/DecoratedCollectionTest.Java

MustacheFactory mf = new DefaultMustacheFactory();
Mustache test = mf.compile(new StringReader("{{#test}}{{#first}}[{{/first}}{{^first}}, {{/first}}\"{{value}}\"{{#last}}]{{/last}}{{/test}}"), "test");
StringWriter sw = new StringWriter();
test.execute(sw, new Object() {
    Collection test = new DecoratedCollection(Arrays.asList("one", "two", "three"));
}).flush();
System.out.println(sw.toString());
0
王子1986

Le moyen le plus simple que j'ai trouvé était de rendre la liste, puis de supprimer le dernier caractère.

  1. Rendez moustache.
  2. Supprimez tout espace blanc avant et après la chaîne.
  3. Puis supprimez le dernier caractère

    let renderData = Moustache Render (dataToRender, data); renderData = (renderData.trim ()). substring (0, renderData.length-1)

0

J'ai tendance à penser que c'est une tâche bien adaptée aux CSS (comme l'ont répondu d'autres). Cependant, en supposant que vous tentiez de créer un fichier CSV, vous ne disposez pas de HTML et de CSS. En outre, si vous envisagez de modifier les données pour le faire de toute façon, cela pourrait être une façon plus simple de le faire:

var data = {
  "items": [
    {"name": "red"},
    {"name": "green"},
    {"name": "blue"}
  ]
};

// clone the original data. 
// Not strictly necessary, but sometimes its
// useful to preserve the original object
var model = JSON.parse(JSON.stringify(data));

// extract the values into an array and join 
// the array with commas as the delimiter
model.items = Object.values(model.items).join(',');

var html = Mustache.render("{{items}}", model);
0
Jefferey Cave