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


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

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

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

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

шаблон

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

это позволит избежать

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

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

14 66

14 ответов:

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

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

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

и ваш шаблон

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

Я знаю, что это не элегантный, но а усы очень легкие и не обеспечивают таких функций.

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

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

и в вашем шаблоне, инвертированный раздел:

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

чтобы отобразить эту запятую.

чит и использовать 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: ", "    
}

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

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

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

на вопрос о том, предлагает ли усы элегантный способ сделать это, был дан ответ, но мне пришло в голову, что самый элегантный способ сделать это-использовать 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+ и других современных браузерах.

Я не могу думать о многих ситуациях, когда вы хотели бы перечислить неизвестное количество элементов за пределами <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 - это массив.

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

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

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

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

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

как вопрос:

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

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

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

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

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

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

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

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

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

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

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

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

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

Я склонен думать, что это задача, хорошо подходящая для 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);

Если вы используете 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());

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

  1. рендеринг усы.
  2. удалить все пробелы до и после строки.
  3. затем удалите последний символ

    пусть renderedData = Mustache Render(dataToRender, data); renderedData=(renderedData.отделка.))(подстрока (0, renderedData.длина-1)