मूंछें में टेम्प्लेटिंग, अल्पविराम द्वारा अलग किए गए अल्पविराम की सूची को व्यक्त करने का एक सुंदर तरीका है?


83

मैं मस्टैच टेंपलेटिंग लाइब्रेरी का उपयोग कर रहा हूं और एक अनुगामी अल्पविराम के बिना अल्पविराम से अलग सूची बनाने की कोशिश कर रहा हूं , जैसे

लाल, हरा, नीला

अनुगामी अल्पविराम के साथ एक सूची बनाना सीधा है, संरचना को देखते हुए

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

और टेम्पलेट

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

इसका समाधान होगा

लाल, हरे, नीले,

हालांकि मैं अनुगामी अल्पविराम के बिना मामले को व्यक्त करने का एक सुंदर तरीका नहीं देख सकता। मैं हमेशा टेम्पलेट में पास करने से पहले सूची में कोड उत्पन्न कर सकता हूं, लेकिन मैं सोच रहा था कि क्या लाइब्रेरी आपको वैकल्पिक दृष्टिकोण प्रदान करती है जैसे कि आपको यह पता लगाने की अनुमति है कि क्या यह टेम्पलेट के भीतर एक सूची में अंतिम आइटम है या नहीं।


मेरा सुझाव है कि अपने कोड में अल्पविराम से अलग की गई सूची बनाएं और इसे एक ही स्ट्रिंग के रूप में मूंछें पास करें। वैकल्पिक और सरल सूचियों की तुलना में अधिक जटिल तर्क क्लासिक प्रोग्रामिंग भाषाओं में लगभग हमेशा अधिक पठनीय है।
यमन

मूंछों से अधिक जटिल टेम्पलेट इंजन यह काफी आसानी से कर सकते हैं। यह उनमें से किसी में बहुत पठनीय नहीं है, हालांकि, और इसे ध्यान में रखते हुए, मूंछें बनाने का निर्णय जितना सरल है उतना ही जानबूझकर किया गया था: डी
योमन

जवाबों:


43

एचआरएम, संदिग्ध, मूंछें डेमो आपको बहुत कुछ दिखाती हैं, firstसंपत्ति के साथ , कि कॉमा डालते समय आपको पता लगाने के लिए जेएसएन डेटा के अंदर तर्क रखना होगा।

तो आपका डेटा कुछ इस तरह दिखाई देगा:

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

और आपका टेम्प्लेट

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

मुझे पता है कि यह सुरुचिपूर्ण नहीं है, लेकिन जैसा कि दूसरों ने उल्लेख किया है कि मूंछें बहुत हल्के हैं और ऐसी विशेषताएं प्रदान नहीं करती हैं।


24
आप डेटा को प्रारूपित भी कर सकते हैं, ताकि "आइटम": ["लाल", "हरा", "नीला"] फिर आप बस एक {{आइटम}} कर सकें, यह पहले से ही अल्पविराम से अलग की गई सूची का उत्पादन करेगा :)
एंथनी चुआ

10
टिप्पणी वास्तव में सही उत्तर होनी चाहिए। बहुत क्लीनर। उपभोक्ता की दृश्य जरूरतों को पूरा करने के लिए अपने डेटा स्रोत को संशोधित करने के लिए इसका वास्तव में खराब रूप है
स्लिकोरी

@AnthonyChua सुरुचिपूर्ण होने के बावजूद, यह (a) दस्तावेजित व्यवहार नहीं हो सकता है और इस प्रकार यह भविष्य में होने वाले परिवर्तनों के अधीन है, हालांकि इसकी संभावना नहीं है, और (b) यह अल्पविराम के बाद स्थान नहीं देता है, इसलिए आपको ऐसा कुछ मिलता है first,second,third
caw 15'14

8
यह केवल एक आइटम को अंतिम आइटम में जोड़ने के लिए कम काम है {"name": "blue", "last": 1}और फिर एक उल्टे खंड का उपयोग करना है{{#items}} {{name}}{{^last}}, {{/last}} {{/items}}
TmTron

1
@ slick86 आपके ऊपर की गई टिप्पणी का परिणाम अल्पविराम द्वारा अलग की गई सूची में है, लेकिन ऐसा नहीं है जिसमें प्रत्येक आइटम डबल-कोट्स में संलग्न है।
GlenRSmith

92

मुझे लगता है कि मॉडल को गतिशील रूप से बदलने का एक बेहतर तरीका है। उदाहरण के लिए, यदि आप जावास्क्रिप्ट का उपयोग कर रहे हैं:

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

और अपने टेम्पलेट में, उलटे अनुभाग का उपयोग करें:

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

उस अल्पविराम को प्रस्तुत करना।


2
मुझे यह पसंद है। हर बार जब मुझे लगता है कि मूंछों में पर्याप्त सुविधा नहीं है, यह इसलिए है क्योंकि मुझे लगता है कि 'पुराना' तरीका जहां टेम्पलेट सब कुछ करता है - ठीक है, मैं सीपीएस से आता हूं।
निकोलस ज़ोज़ोल

1
@ निकोलसोज़ोज़ोल आपको एहसास है कि मूंछें बिल्कुल इस तरह की सादगी को ध्यान में रखकर बनाई गई थीं? : D
तुर्क

@ नाइकोलाज़ोज़ोल वास्तव में जटिल मामलों के लिए, प्रोग्रामिंग भाषा में सीधे तार बनाने के लिए सबसे अच्छा है, और इस तरह एक सरल दृश्य मॉडल बनाते हैं जिसे टेम्पलेट भाषा संभाल सकती है। इस स्थिति में, अल्पविराम से अलग की गई सूची को एक स्ट्रिंग के रूप में कोड के माध्यम से प्रदान किया जाएगा।
फीनिक्स

41

धोखा और सीएसएस का उपयोग करें।

यदि आपका मॉडल है:

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

फिर अपना टेम्प्लेट बनाएं

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

और थोड़ी सीएसएस जोड़ें

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

मैं अनुमान लगा रहा हूं कि कोई कहेगा कि यह प्रस्तुति में मार्कअप डालने का एक बुरा मामला है, लेकिन मुझे नहीं लगता कि यह है। कॉमा को अलग करने वाले मूल्य अंतर्निहित डेटा की व्याख्या करना आसान बनाने के लिए एक प्रस्तुति निर्णय है। यह प्रविष्टियों पर फ़ॉन्ट रंग को बदलने के समान है।


यह ध्यान दिया जाना चाहिए कि यह IE9 + में ही संगत है, इसलिए यदि आपको पुराने ब्राउज़रों का समर्थन करने की आवश्यकता है, तो आपको एक और दृष्टिकोण का उपयोग करना पड़ सकता है
PoeHaH

1
इससे यह अनुमान लगाया जाता है कि मूंछें वेब-पेजों के लिए इस्तेमाल की जा रही हैं - इसके बहुत सारे उपयोग भी हैं
tddmonkey

30

यदि आप jmustache का उपयोग करते हैं , तो आप विशेष -firstया -lastचर का उपयोग कर सकते हैं :

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

4
मुझे पता है कि ओपी जावास्क्रिप्ट मूंछ पुस्तकालय का जिक्र कर रहा था, लेकिन इससे अन्य jmustache उपयोगकर्ताओं (मेरे जैसे) को मदद मिल सकती है जो इस पृष्ठ को ढूंढते हैं।
dbort

उत्तर के लिए बहुत बहुत धन्यवाद। मैंने इसका उपयोग स्प्रिंगबूट के साथ एक टेम्पलेट प्रदान करने के लिए भी किया। मॉडल को बदलने की आवश्यकता नहीं है। मैं वास्तव में इस सुविधा की तलाश में था। मुझे आश्चर्य है कि अगर समानता नियंत्रण (जैसे {{#something=TEXT}}) हैं
JeanValjean

8

मैं कई स्थितियों के बारे में सोच नहीं कर सकते तुम कहाँ आइटम एक के बाहर के एक अज्ञात संख्या सूची करना चाहते हैं <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एक ऐरे है।


सुंदर बहुत खूबसूरत लगता है! मान लें कि #if और @index मूंछों के सभी या अधिकांश कार्यान्वयन में उपलब्ध हैं ... ध्यान रखें, हम में से कई मूंछें उपयोगकर्ता HTML उत्पन्न नहीं कर रहे हैं, भले ही वह सबसे आम उपयोग-मामला हो।
स्पाइक 0xff

यह एक भयानक समाधान है, एक आकर्षण की तरह काम करता है। इस उत्तर में आने वाले किसी भी व्यक्ति के लिए शीर्ष, यदि आप परिणाम को HTML टैग में लपेटना चाहते हैं, तो ऐसा करें {{.}}
नेटओपरेटर विब्बी

यह सही पॉइंटर था। ऐसा प्रतीत होता है कि अब आप एक बेहतर नियंत्रण के लिए [पहले] और [अंतिम] सशर्त का उपयोग कर सकते हैं। stackoverflow.com/questions/11479094/…
मैक्सिमम

6

इस सवाल का कि क्या मूंछें ऐसा करने का एक सुरुचिपूर्ण तरीका प्रस्तुत करती हैं, इसका उत्तर दिया गया है, लेकिन मेरे साथ ऐसा हुआ है कि ऐसा करने का सबसे सुरुचिपूर्ण तरीका मॉडल को बदलने के बजाय CSS का उपयोग करना हो सकता है।

टेम्पलेट:

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

सीएसएस:

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

यह IE8 + और अन्य आधुनिक ब्राउज़रों में काम करता है।


5

मूंछों में ऐसा करने का कोई अंतर्निहित तरीका नहीं है। आपको इसका समर्थन करने के लिए अपने मॉडल को बदलना होगा।

टेम्प्लेट में इसे लागू करने का एक तरीका उल्टे चयन टोपी {{^last}} {{/last}}टैग का उपयोग करना है । यह केवल सूची में अंतिम आइटम के लिए पाठ को छोड़ देगा ।

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

या आप ", "ऑब्जेक्ट के रूप में सीमांकक स्ट्रिंग जोड़ सकते हैं , या आदर्श रूप से बेस क्लास यदि आप उस भाषा का उपयोग कर रहे हैं जिसमें वंशानुक्रम है, तो " "इस तरह के अंतिम तत्व के लिए एक रिक्त स्ट्रिंग में "सीमांकक" सेट करें:

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

1
बस स्पष्ट होने के लिए, इस काम के लिए इनपुट डेटा में कुछ वास्तव में "अंतिम" नाम होना चाहिए। सही बात?
FrustratedWithFormsDesigner

1
सही है, आपको अपने मॉडल को एक बूलियन संपत्ति जोड़कर बदलना होगा last। फिर संग्रह में अंतिम आइटम सेट करें last=true
cosbor11

1
इस मामले में "मॉडल" वास्तव में एक कॉन्फ़िगर फ़ाइल है जिसे उपयोगकर्ता संपादित कर सकते हैं ... मुझे नहीं लगता कि मैं उन्हें किसी सूची में सही आइटम पर "अंतिम" ठीक से डालने के लिए विश्वास करना चाहता हूं।
FrustratedWithFormsDesigner

टेम्प्लेट इंजन का उपयोग करने के लिए आप किस भाषा का उपयोग कर रहे हैं?
cosbor11

2
उस स्थिति में रनटाइम के दौरान configफ़ाइल प्रतिनिधित्व को एक अजगर ऑब्जेक्ट में परिवर्तित करें । मुझे लगता है कि विन्यास में jsonया xmlसही है? फिर, इससे पहले कि आप इसे टेम्पलेट इंजन में पास करें, संग्रह का अंतिम आइटम प्राप्त करें और lastसंपत्ति को लागू करें ।
cosbor11

3

JSON डेटा के लिए मेरा सुझाव है:

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

,अंतिम गुण के बाद regexp किसी भी बाएं लटका को हटा देगा ।

यह ,",}" या "," "" स्ट्रिंग मानों को भी हटा देगा , इसलिए सुनिश्चित करें कि आप जानते हैं कि डेटा आपके ईमेल में डाला जाएगा


यह निश्चित रूप से मेरे लिए चाल थी क्योंकि मेरे पास एक JSON स्कीमा है। धन्यवाद!
ययाजिनी

2

जैसा सवाल है:

अनुगामी अल्पविराम के बिना अल्पविराम से अलग सूची को व्यक्त करने का एक सुंदर तरीका है?

फिर डेटा बदलना - जब अंतिम आइटम पहले से ही निहित है, तो यह सरणी में अंतिम आइटम है - सुरुचिपूर्ण नहीं है।

किसी भी मूंछें टेम्प्लेटिंग भाषा जिसमें सरणी सूचक हैं यह ठीक से कर सकते हैं,। अर्थात। डेटा में कुछ भी जोड़े बिना । इसमें हैंडलबार, ractive.js, और अन्य लोकप्रिय मूंछ कार्यान्वयन शामिल हैं।

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

1
ठीक। लेकिन मूंछें नहीं हैंif
mauron85

@ mauron85 वास्तव में। मैं (और कई अन्य) मूंछों को मूल मूंछों से प्रेरित विभिन्न अस्थायी भाषाओं के लिए एक बहुवचन के रूप में उपयोग करते हैं।
मिकमेकाना

1

सबसे आसान तरीका मुझे सूची प्रस्तुत करना और फिर अंतिम चार निकालना था।

  1. मूंछें मूंछ।
  2. स्ट्रिंग से पहले और बाद में किसी भी सफेद स्थान को हटा दें।
  3. फिर अंतिम चरित्र को हटा दें

    letDDData = Mustache रेंडर (dataToRender, data); रेंडरडैट = (रेंडरडैट.ट्रिम ())। सबरिंग (0, रेंडरडैट.लिफ्टिंग -1)


1

हैंडलबार्स का उपयोग करने के मामले में, एक विकल्प है, जो मूंछों की क्षमताओं का विस्तार करता है, आप एक @data चर का उपयोग कर सकते हैं:

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

अधिक जानकारी: http://handlebarsjs.com/reference.html#data


3
हैंडलबार्स मूंछों के ऊपर बनते हैं, चारों ओर नहीं
एंडी जोन्स

0

दिलचस्प। मुझे पता है कि यह एक प्रकार का आलसी है, लेकिन मैं आमतौर पर मान को असाइन करने की बजाय मान असाइनमेंट में टेंपलेट करके इसे प्राप्त करता हूं।

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

0

मुझे लगता है कि यह सीएसएस के अनुकूल एक कार्य है (जैसा कि दूसरों द्वारा उत्तर दिया गया है)। हालाँकि, यह मानकर कि आप 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);

0

यदि आप जावा का उपयोग कर रहे हैं, तो आप निम्नलिखित का उपयोग कर सकते हैं:

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

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मैं अभी भी एक जवाब जोड़ना चाहता था जो एक और दृष्टिकोण प्रदान करता है।

मुख्य उत्तर

मूंछें लैम्ब्डा का समर्थन करती हैं, ( प्रलेखन देखें ) तो कोई इसे इस तरह लिख सकता है:

टेम्पलेट:

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

हैश:

    {
      "items": [
        {"name": "red"},
        {"name": "green"},
        {"name": "blue"}
      ]
      "removeTrailingComma": function() {
        return function(text, render) {
          var original = render(text);
          return original.substring(0, original.length - 2);
        }
      }
    }

आउटपुट:

लाल, हरा, नीला

टिप्पणी

व्यक्तिगत रूप से, मुझे दूसरों पर यह दृष्टिकोण पसंद है, क्योंकि IMHO मॉडल को केवल यह निर्दिष्ट करना चाहिए कि क्या प्रस्तुत किया गया है और कैसे नहीं इसे प्रस्तुत किया गया है। तकनीकी रूप से, लैम्ब्डा मॉडल का हिस्सा है, लेकिन इरादा बहुत अधिक स्पष्ट है।

मैं अपने स्वयं के OpenApi जनरेटर लिखने के लिए इस दृष्टिकोण का उपयोग करता हूं। वहाँ, मूंछें जावा द्वारा लपेटी जाती हैं, लेकिन कार्यक्षमता बहुत अधिक है। यह वह लम्हा है जो मेरे लिए जैसा दिखता है: (कोटलिन में)

    override fun addMustacheLambdas(): ImmutableMap.Builder<String, Mustache.Lambda> =
        super.addMustacheLambdas()
            .put("lowerCase", Mustache.Lambda { fragment, writer ->
                writer.write(fragment.execute().toLowerCase())
            })
            .put("removeLastComma", Mustache.Lambda { fragment, writer ->
                writer.write(fragment.execute().removeSuffix(","))
            })
            .put("printContext", Mustache.Lambda { fragment, writer ->
                val context = fragment.context()
                println(context) // very useful for debugging if you are not the author of the model
                writer.write(fragment.execute())
            })

0

डायनामिक 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", "john.wick@hotmail.com"],
      ["Donald", "Duck", "donald.duck@ducks.com"],
      ["Anonymous", "Anonymous","jack.kowalski@gmail.com"]
    ];

    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/


0

अधिक जटिल परिदृश्यों में, कई कारणों से एक दृश्य मॉडल वांछनीय है। यह मॉडल के डेटा को इस तरीके से प्रदर्शित करता है जो प्रदर्शन के लिए बेहतर है या, इस मामले में, टेम्पलेट प्रसंस्करण।

यदि आप एक दृश्य मॉडल का उपयोग कर रहे हैं, तो आप आसानी से सूचियों का प्रतिनिधित्व कर सकते हैं जो आपके लक्ष्य को सुविधाजनक बनाता है।

नमूना:

{
    name: "Richard",
    numbers: [1, 2, 3]
}

देखें मॉडल:

{
    name: "Richard",
    numbers: [
        { first: true, last: false, value: 1 },
        { first: false, last: false, value: 2 },
        { first: false, last: true, value: 3 }
    ]
}

दूसरी सूची रिप्रेसन टाइप करने के लिए भयानक है, लेकिन कोड से बनाने के लिए बेहद सरल है। अपने मॉडल को व्यू मॉडल में मैप करते समय, बस हर उस सूची को बदलें जिसकी आपको ज़रूरत है firstऔर lastइस प्रतिनिधित्व के साथ।

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
}

अनबाउंड सूचियों के मामले में, आप केवल सेट firstऔर ओटिट कर सकते हैंlast , क्योंकि उनमें से एक अनुगामी अल्पविराम से बचने के लिए पर्याप्त है।

का उपयोग कर first:

{{#numbers}}{{^first}}, {{/first}}{{value}}{{/numbers}}

का उपयोग कर last:

{{#numbers}}{{value}}{{^last}}, {{/last}}{{/numbers}}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.