Używam biblioteki szablonów Mustache i próbuję wygenerować listę oddzieloną przecinkami bez końcowego przecinka, np
czerwony, zielony, niebieski
Tworzenie listy z końcowym przecinkiem jest proste, biorąc pod uwagę strukturę
{
"items": [
{"name": "red"},
{"name": "green"},
{"name": "blue"}
]
}
i szablon
{{#items}}{{name}}, {{/items}}
to rozwiąże
czerwony, zielony, niebieski,
Jednak nie widzę eleganckiego sposobu wyrażenia przypadku bez końcowego przecinka. Zawsze mogę wygenerować listę w kodzie przed przekazaniem jej do szablonu, ale zastanawiałem się, czy biblioteka oferuje alternatywne podejście, takie jak umożliwienie wykrycia, czy jest to ostatnia pozycja na liście w szablonie.
Odpowiedzi:
Hrm, wątpliwe, demo wąsów prawie pokazuje ci, z tą
first
właściwością, że musisz mieć logikę wewnątrz danych JSON, aby dowiedzieć się, kiedy wstawić przecinek.Twoje dane wyglądałyby więc mniej więcej tak:
i twój szablon
Wiem, że nie jest elegancki, ale jak wspominali inni Mustache jest bardzo lekki i nie ma takich funkcji.
źródło
first,second,third
.{"name": "blue", "last": 1}
a następnie użyć sekcji odwróconej{{#items}} {{name}}{{^last}}, {{/last}} {{/items}}
Myślę, że lepszym sposobem jest dynamiczna zmiana modelu. Na przykład, jeśli używasz JavaScript:
aw szablonie użyj odwróconej sekcji:
aby wyrenderować ten przecinek.
źródło
Oszukuj i używaj CSS.
Jeśli Twój model to:
następnie utwórz swój szablon
i dodaj trochę CSS
Myślę, że ktoś powie, że to zły przypadek umieszczania znaczników w prezentacji, ale nie sądzę. Wartości oddzielające przecinki to decyzja dotycząca prezentacji, która ułatwia interpretację danych bazowych. Jest to podobne do zmiany koloru czcionki we wpisach.
źródło
Jeśli używasz jmustache , możesz użyć specjalnych
-first
lub-last
zmiennych:źródło
{{#something=TEXT}}
)Nie przychodzi mi do głowy wiele sytuacji, w których chciałbyś wymienić nieznaną liczbę elementów poza
<ul>
lub<ol>
, ale tak byś to zrobił:…będzie produkować:
Pamiętaj, że to kierownica.
@index
będzie działać, jeślitest
jest tablicą.źródło
{{.}}
.Odpowiedziano na pytanie, czy Mustache oferuje elegancki sposób, aby to zrobić, ale przyszło mi do głowy, że najbardziej eleganckim sposobem na to może być użycie CSS, a nie zmiana modelu.
Szablon:
CSS:
Działa to w IE8 + i innych nowoczesnych przeglądarkach.
źródło
W Mustache nie ma na to wbudowanego sposobu. Musisz zmienić swój model, aby go wspierać.
Jednym ze sposobów zaimplementowania tego w szablonie jest użycie odwróconego
{{^last}} {{/last}}
tagu kapeluszowego wyboru . Pominie tekst tylko dla ostatniej pozycji na liście.Lub możesz dodać ciąg separatora jako
", "
do obiektu lub najlepiej klasę bazową, jeśli używasz języka, który ma dziedziczenie, a następnie ustawić „delimiter” na pusty ciąg" "
dla ostatniego elementu w następujący sposób:źródło
last
. Następnie ustaw ostatnią pozycję w kolekcji nalast=true
.config
reprezentację pliku na obiekt Pythona. Zgaduję config jestjson
lubxml
, prawda? Następnie, zanim przekażesz go do silnika szablonów, pobierz ostatni element kolekcji i zastosujlast
właściwość.W przypadku danych JSON sugeruję:
Mustache.render(template, settings).replace(/,(?=\s*[}\]])/mig,'');
Wyrażenie regularne usunie
,
zawieszenie po ostatnich właściwościach.Spowoduje to również usunięcie
,
z ciągów wartości zawierających „,}” lub „,]”, więc upewnij się, że wiesz, jakie dane zostaną umieszczone w Twoim JSONźródło
Ponieważ pytanie brzmi:
Zatem zmiana danych - gdy bycie ostatnim elementem jest już domniemane przez to, że jest ostatnim elementem tablicy - nie jest eleganckie.
Każdy język szablonów wąsów, który ma indeksy tablicowe, może to zrobić poprawnie. to znaczy. bez dodawania czegokolwiek do danych . Obejmuje to kierownice, ractive.js i inne popularne implementacje wąsów.
źródło
if
Najprostszym sposobem, jaki znalazłem, było wyrenderowanie listy, a następnie usunięcie ostatniego znaku.
Następnie usuń ostatni znak
let renderingData = Mustache Render (dataToRender, dane); renderingData = (renderingData.trim ()). substring (0, renderingData.length-1)
źródło
W bardziej złożonych scenariuszach model widoku jest pożądany z wielu powodów. Przedstawia dane modelu w sposób lepiej dostosowany do wyświetlania lub, w tym przypadku, przetwarzania szablonu.
Jeśli używasz modelu widoku, możesz łatwo przedstawić listy w sposób ułatwiający osiągnięcie celu.
Model:
{ name: "Richard", numbers: [1, 2, 3] }
Zobacz model:
{ name: "Richard", numbers: [ { first: true, last: false, value: 1 }, { first: false, last: false, value: 2 }, { first: false, last: true, value: 3 } ] }
Reprezentacja drugiej listy jest okropna do wpisania, ale niezwykle prosta do utworzenia z kodu. Podczas mapowania modelu do modelu widoku, po prostu zastąp każdą listę, której potrzebujesz
first
ilast
dla której, taką reprezentacją.function annotatedList(values) { let result = [] for (let index = 0; index < values.length; ++index) { result.push({ first: index == 0, last: index == values.length - 1, value: values[index] }) } return result }
W przypadku list nieograniczonych można również tylko ustawiać
first
i pomijaćlast
, ponieważ jedna z nich wystarczy, aby uniknąć końcowego przecinka.Używając
first
:Używając
last
:źródło
W przypadku, gdy użycie Handlebars jest opcją, która rozszerza możliwości Mustache, możesz użyć zmiennej @data:
Więcej informacji: http://handlebarsjs.com/reference.html#data
źródło
Ciekawy. Wiem, że to trochę leniwe, ale zwykle omijam to, umieszczając szablony w przypisaniu wartości, zamiast próbować ograniczać wartości przecinkami.
źródło
Wydaje mi się, że jest to zadanie dobrze dopasowane do CSS (na co odpowiadali inni). Jednak zakładając, że próbujesz zrobić coś takiego, jak utworzenie pliku CSV, nie będziesz mieć dostępnego HTML i CSS. Ponadto, jeśli zastanawiasz się nad zmodyfikowaniem danych, aby to zrobić, może to być prostszy sposób:
źródło
Jeśli korzystasz z Java, możesz użyć:
https://github.com/spullara/mustache.java/blob/master/compiler/src/test/java/com/github/mustachejava/util/DecoratedCollectionTest.java
źródło
Wiem, że to stare pytanie, ale nadal chciałem dodać odpowiedź, która zawiera inne podejście.
Główna odpowiedź
Mustache obsługuje lambdy ( patrz dokumentacja ), więc można to zapisać w ten sposób:
Szablon:
Haszysz:
Wynik:
Komentarz
Osobiście podoba mi się to podejście nad innymi, ponieważ IMHO model powinien określać tylko, co jest renderowane, a nie jak jest renderowany. Technicznie lambda jest częścią modelu, ale cel jest znacznie bardziej jasny.
Używam tego podejścia do pisania własnych generatorów OpenApi. Tam Mustache jest opakowany przez Javę, ale funkcjonalność jest prawie taka sama. Tak wygląda u mnie tworzenie lambd: (w Kotlinie)
źródło
Używam do tego funkcji niestandardowych, w moim przypadku podczas pracy z dynamicznymi zapytaniami SQL.
$(document).ready(function () { var output = $("#output"); var template = $("#test1").html(); var idx = 0; var rows_count = 0; var data = {}; data.columns = ["name", "lastname", "email"]; data.rows = [ ["John", "Wick", "[email protected]"], ["Donald", "Duck", "[email protected]"], ["Anonymous", "Anonymous","[email protected]"] ]; data.rows_lines = function() { let rows = this.rows; let rows_new = []; for (let i = 0; i < rows.length; i++) { let row = rows[i].map(function(v) { return `'${v}'` }) rows_new.push([row.join(",")]); } rows_count = rows_new.length; return rows_new } data.last = function() { return idx++ === rows_count-1; // omit comma for last record } var html = Mustache.render(template, data); output.append(html); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/4.0.1/mustache.min.js"></script> <h2>Mustache example: Generate SQL query (last item support - omit comma for last insert)</h2> <div id="output"></div> <script type="text/html" id="test1"> INSERT INTO Customers({{{columns}}})<br/> VALUES<br/> {{#rows_lines}} ({{{.}}}){{^last}},{{/last}}<br/> {{/rows_lines}} </script>
https://jsfiddle.net/tmdoit/4p5duw70/8/
źródło