В шаблонах Mustache есть элегантный способ выражения списка, разделенного запятыми, без конечной запятой?

Я использую библиотеку шаблонов Mustache и пытаюсь создать список, разделенный запятыми, без конечной запятой, например

красный, зеленый, синий

Создание списка с конечной запятой является простым, учитывая структуру

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

и шаблон

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

это решит

красный, зеленый, синий,

Однако я не вижу элегантного способа выражения аргумента без конечной запятой. Я всегда могу сгенерировать список в коде, прежде чем передавать его в шаблон, но мне было интересно, предлагает ли библиотека альтернативный подход, например, разрешить вам определять, является ли это последним элементом в списке в шаблоне.

Ответ 1

Hrm, сомнительно, демон усов в значительной степени показывает вам, с свойством first, что вы должны иметь логику внутри данные JSON, чтобы выяснить, когда положить запятую.

Итак, ваши данные будут выглядеть примерно так:

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

и ваш шаблон

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

Я знаю, что это не изящно, а как упоминалось другими людьми. Усы очень легкие и не предоставляют таких функций.

Ответ 2

Я думаю, что лучший способ - изменить модель динамически. Например, если вы используете JavaScript:

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

и в вашем шаблоне используйте инвертированный раздел:

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

чтобы сделать эту запятую.

Ответ 3

Обмануть и использовать CSS.

Если ваша модель:

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

затем создайте свой шаблон

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

и добавьте немного CSS

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

Я предполагаю, что кто-то скажет, что это плохой случай размещения разметки в презентации, но я не думаю, что это так. Значения разделяемых запятой - это решение для презентации, облегчающее интерпретацию базовых данных. Он похож на чередование цвета шрифта в записях.

Ответ 4

Если вы используете jmustache, вы можете использовать специальные переменные -first или -last:

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

Ответ 5

Вопрос о том, предлагает ли Mustache элегантный способ сделать это, был дан ответ, но мне пришло в голову, что самым изящным способом сделать это может быть использование CSS, а не изменение модели.

Шаблон:

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

CSS:

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

Это работает в IE8 + и других современных браузерах.

Ответ 6

Я не могу придумать много ситуаций, когда вы хотите перечислить неизвестное количество элементов вне <ul> или <ol>, но так вы это сделаете:

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

... будет производить:

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

Это Руки, заметьте. @index будет работать, если test является массивом.

Ответ 7

В Усаче нет встроенного способа сделать это. Вы должны изменить свою модель, чтобы поддержать ее.

Один из способов реализовать это в шаблоне - использовать тэг инвертированного выделения {{^last}} {{/last}}. Он будет пропускать текст только для элемента last в списке.

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

Или вы можете добавить строку разделителя как ", " к объекту или, в идеале, базовый класс, если вы используете язык с наследованием, затем установите "разделитель" в пустую строку " " для последнего элемента например:

{{#items}}
    {{name}}{{delimiter}}
{{/items}}

Ответ 8

Как вопрос:

Есть ли элегантный способ выражения списка, разделенного запятой, без конечной запятой?

Затем изменение данных - когда последний элемент уже подразумевается, будучи последним элементом в массиве, не является элегантным.

Любой язык шаблонов усов, который имеет индексы массивов, может сделать это правильно. то есть. без добавления каких-либо данных. Это включает в себя handlebars, ractive.js и другие популярные реализации усов.

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

Ответ 9

Для данных JSON я предлагаю:

Mustache.render(template, settings).replace(/,(?=\s*[}\]])/mig,'');

Регулярное выражение будет удалять любые оставшиеся , после последних свойств.

Это также удалит , из строковых значений contining ",}" или ",]", поэтому убедитесь, что вы знаете, какие данные будут помещены в ваш JSON

Ответ 10

Как Mustache стоит на Handlebars, почему бы не использовать переменную @data? Я нашел этот самый чистый вариант:

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

Дополнительная информация: http://handlebarsjs.com/reference.html#data

Ответ 11

Интересно. Я знаю, что это немного лениво, но я обычно оборачиваю это путем шаблонирования в присваивании значений, а не для запятой, чтобы разграничить значения.

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

Ответ 12

Я склонен думать, что это задача, хорошо подходящая для CSS (как утверждают другие). Однако, предполагая, что вы пытаетесь сделать что-то вроде создания CSV файла, у вас не будет HTML и CSS для вас. Кроме того, если вы все же планируете модифицировать данные, это может быть более аккуратным способом:

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

Ответ 13

Если вы используете java, вы можете использовать следующее:

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