सवाल हैशपैप कुंजी पर फ्रीमार्कर पुनरावृत्ति


फ्रीमार्कर में दो संग्रह डेटाटाइप, सूचियां और हैशपैप्स हैं क्या हम हैशैप कुंजी पर पुन: प्रयास करने का कोई तरीका है जैसे हम सूचियों के साथ करते हैं?

तो अगर मेरे पास डेटा के साथ एक var है तो कहें:

user : {
  name : "user"
  email : "looser@everything.com"
  homepage : "http://nosuchpage.org"
}

मैं अपने उपयोगकर्ता के गुणों को उनके मूल्य के साथ मुद्रित करना चाहता हूं। यह अमान्य है, लेकिन लक्ष्य स्पष्ट है:

<#list user.props() as prop>
  ${prop} = ${user.get(prop)}
</#list>

76
2017-09-30 12:22


मूल




जवाब:


संपादित करें: FreeMarker 2.3.25 और ऊपर, विशेष रूप से नहीं, इस समाधान का उपयोग न करें .get(prop)। अन्य उत्तरों देखें।

आप अंतर्निर्मित का उपयोग करते हैं चांबियाँ समारोह, उदा। यह काम करना चाहिए:

<#list user?keys as prop>
    ${prop} = ${user.get(prop)}
</#list>  

94
2017-09-30 12:27



सिंटैक्स नवीनतम संस्करण में अलग है, जैसा कि मैंने अपने उत्तर में पोस्ट किए गए लिंक में दिखाया है। मुझे एहसास है कि यह एक पुराना सवाल है, लेकिन यह Google पर अत्यधिक रैंकिंग में आता है। - Nick Spacek
सिर्फ एक नोट - आप उपयोग कर सकते हैं ${user[prop]} एक शॉर्टेंड के रूप में - Bozho
यह एक प्रदर्शन रिसाव है: प्रत्येक कुंजी के लिए, इसे मूल्य पुनर्प्राप्त करने की आवश्यकता है। एंट्रीसेट () में इटरेटिंग में उस समस्या नहीं है। - Geoffrey De Smet
$ {उपयोगकर्ता [प्रोप] होना चाहिए} - dns
यह $ {map [key]} है, देखें freemarker.org/docs/ref_builtins_hash.html - david_p


एफवाईआई, ऐसा लगता है कि मूल्यों को पुनः प्राप्त करने के लिए वाक्यविन्यास बदल गया है:

http://freemarker.sourceforge.net/docs/ref_builtins_hash.html

<#assign h = {"name":"mouse", "price":50}>
<#assign keys = h?keys>
<#list keys as key>${key} = ${h[key]}; </#list>

47
2018-03-30 17:24



यह वाक्यविन्यास अलग कैसे है? - Parker
मुझे लगता है कि यह वह था जो अब काम नहीं करता था। - Nick Spacek
अच्छा जवाब ;-) ध्यान दें कि आपको अपना मूल्य प्रिंट करते समय शून्य के लिए एक चेक करना पड़ सकता है, <#if h [key] ??> $ {key} = $ {h [key]}; </ # यदि> - Brad Parks
वाक्यविन्यास नहीं बदला गया था। दोनों [key] तथा .get(key) प्राचीन काल से मौजूद है। .get(key) एफटीएल के लिए कोई विशेष नहीं है, यह सिर्फ सार्वजनिक जावा विधि को बुला रहा है। लेकिन अगर आप फ्रीमार्कर को बेनकाब करने के लिए कॉन्फ़िगर किया गया था तो आप इसका उपयोग कर सकते हैं Map तरीकों। - ddekany
जब पुनरावृत्त होता है, तो मुझे विधियां मिलती हैं (getClass, हैशकोड, बराबर, प्राप्त, टोस्टिंग, कक्षा) ... हालांकि, मुझे 'id' जैसी कोई भी प्रॉपर्टी नहीं दिखाई दे रही है, जो मैं चाहता हूं कि मैं एक सूची प्राप्त करूं। कोई सुझाव है कि उस हैश से गैर-विधि गुणों की सूची कैसे प्राप्त करें? मुझे उन संपत्ति के नामों को जानना होगा। : | - MaxRocket


2.3.25 के बाद से, इसे इस तरह करें:

<#list user as propName, propValue>
  ${propName} = ${propValue}
</#list>

ध्यान दें कि यह गैर-स्ट्रिंग कुंजियों के साथ भी काम करता है (विपरीत map[key], जिसे लिखा जाना था map?api.get(key) फिर)।

2.3.25 से पहले मानक समाधान था:

<#list user?keys as prop>
  ${prop} = ${user[prop]}
</#list>

हालांकि, कुछ वास्तव में पुराने फ्रीमार्कर एकीकरण एक अजीब विन्यास का उपयोग करते हैं, जहां जनता Map तरीकों (जैसे getClass) कुंजी के रूप में दिखाई देते हैं। ऐसा होता है क्योंकि वे शुद्ध उपयोग कर रहे हैं BeansWrapper (के बजाय DefaultObjectWrapper) किसका simpleMapWrapper संपत्ति पर छोड़ा गया था false। आपको ऐसे सेटअप से बचना चाहिए, क्योंकि यह वास्तविक तरीकों को मिश्रित करता है Map प्रविष्टियों। लेकिन यदि आप इस तरह के दुर्भाग्यपूर्ण सेटअप में भाग लेते हैं, तो स्थिति से बचने का तरीका खुला जावा विधियों का उपयोग कर रहा है, जैसे कि user.entrySet(), user.get(key), आदि, और टेम्पलेट भाषा संरचनाओं का उपयोग नहीं कर रहे हैं ?keys या user[key]


24
2017-07-08 17:25



यह पूरी तरह से काम करता है। लेकिन, मुझे स्प्रिंग्ससोर्स आईडीई में त्रुटियां दिखाई दे रही हैं। कोई विचार यह तय करने के लिए कैसे? धन्यवाद - harshavmb
@harshavmb क्या त्रुटियां? क्या यह पुरानी फ्रीमार्कर प्लगइन का उपयोग करता है, जो पुराने फ्रीमार्कर संस्करण के साथ आता है? - ddekany
ऐसा मत सोचो। Jboss उपकरण से नवीनतम डाउनलोड किया है। मैं अन्य मशीन पर कोशिश करूंगा और आपको बता दूंगा। - harshavmb
@harshavmb अगर आप कुछ ऐसा दर्ज करते हैं ${x?nosuchthing} और आप इसके ऊपर होवर करते हैं, दिखाए गए त्रुटि संदेश से पता चलता है कि यह किस फ्रीमार्कर संस्करण का उपयोग करता है। यह होना चाहिए 2.3.25-incubating। - ddekany
अजीब, मैंने बस मैक में कोशिश की और इस मुद्दे को दोहराना नहीं कर सका। समस्या केवल मेरे वीएम के साथ ही प्रतीत होती है। मैं जार संस्करण पर एक नज़र डालेगा। हालांकि, यह संपादक में सिर्फ एक त्रुटि है, लेकिन कोड सही ढंग से निष्पादित किया गया था। - harshavmb


अगर एक का उपयोग कर रहे हैं BeansWrapper Expose.SAFE या Expose.ALL के एक्सपोजर स्तर के साथ, फिर एंट्री सेट को पुन: सक्रिय करने के मानक जावा दृष्टिकोण को नियोजित किया जा सकता है:

उदाहरण के लिए, निम्नलिखित Freemarker में काम करेगा (कम से कम संस्करण 2.3.1 9 के बाद से):

<#list map.entrySet() as entry>  
  <input type="hidden" name="${entry.key}" value="${entry.value}" />
</#list>

स्ट्रैट्स 2 में, उदाहरण के लिए, बीनवापर का एक विस्तार इस तरह के पुनरावृत्ति के तरीके को अनुमति देने के लिए एक्सपोजर स्तर के साथ प्रयोग किया जाता है।


12
2018-05-07 14:48



क्या आपने वास्तव में यह कोशिश की है? क्योंकि मुझे एक मिला है InvalidReferenceException जब मैंने कोशिश की, जबकि map?keys काम किया। - kdgregory
यह केवल उपयोग करते समय काम करता है freemarker.ext.beans.BeansWrapper ऑब्जेक्ट रैपर के रूप में। अन्यथा Mapएस स्वचालित रूप से एक में लपेटा जाएगा SimpleHash ऑब्जेक्ट जो समर्थन नहीं करता है #entrySet()। (देख freemarker.sourceforge.net/docs/api/freemarker/template/...) - Koraktor
आप सही हैं, और मैंने आपकी टिप्पणी को दर्शाने के लिए अपना जवाब अपडेट कर दिया है। अच्छा लग रहा है! - rees
उपरोक्त एफटीएल के अंदर बनाए गए हैंश के लिए यह अच्छी तरह से काम नहीं करेगा, विशेष रूप से यदि आप बीनवापर के साथ स्प्रिंग फ्रीमार्कर रिज़ॉल्वर का उपयोग कर रहे हैं। Ftl फ़ाइल के अंदर घोषित हैश को लपेटा नहीं गया है और अभी भी एक हैश का उपयोग कर एक हैश उपयोग योग्य होगा। - skipy
शुद्ध का प्रयोग न करें BeansWrapper, कम से कम इसके डिफ़ॉल्ट के साथ, जहां simpleMapWrapper है false। यह बहुत भ्रमित हो जाता है, क्योंकि यह विधि नामों के साथ कुंजी मिश्रण करता है। अगर आपको कॉल करने की ज़रूरत है entrySet(), बस एक "साफ" ऑब्जेक्ट रैपर का उपयोग करते रहें, जैसे कि डिफ़ॉल्ट, और लिखें map?api.entrySet() यदि आपको कुंजी के बजाय जावा एपीआई तक पहुंचने की आवश्यकता है। - ddekany


वस्तुओं को बदलना

यदि आपकी नक्शा कुंजी एक वस्तु है और स्ट्रिंग नहीं है, तो आप इसे फ्रीमार्कर का उपयोग करके पुन: सक्रिय कर सकते हैं।

1) मानचित्र को नियंत्रक में एक सूची में कनवर्ट करें:

List<Map.Entry<myObjectKey, myObjectValue>> convertedMap  = new ArrayList(originalMap.entrySet());

2) Freemarker टेम्पलेट में मानचित्र को इटरेट करें, कुंजी में ऑब्जेक्ट तक पहुंच और ऑब्जेक्ट में ऑब्जेक्ट तक पहुंच:

<#list convertedMap as item>
    <#assign myObjectKey = item.getKey()/>
    <#assign myObjectValue = item.getValue()/>
    [...]
</#list>

2
2018-06-20 08:42





आप अपने जावा प्रोग्राम में सेट की गई कुंजी तक पहुंचने के लिए एक सिंगल कोट का उपयोग कर सकते हैं।

यदि आप इस तरह जावा में एक नक्शा सेट करते हैं

Map<String,Object> hash = new HashMap<String,Object>();
hash.put("firstname", "a");
hash.put("lastname", "b");

Map<String,Object> map = new HashMap<String,Object>();
map.put("hash", hash);

फिर आप इस तरह फ्रीमार्कर में 'हैश' के सदस्यों तक पहुंच सकते हैं -

${hash['firstname']}
${hash['lastname']}

आउटपुट:

a
b

1
2018-03-19 18:28



जो दिखाता है कि व्यक्तिगत कुंजी को कैसे संबोधित किया जाए, लेकिन सवाल पूछता है कि कैसे पुनरावृत्ति करें - Lambart


पूर्णता के लिए, उल्लेखनीय है कि हाल ही में फ्रीमार्कर में खाली संग्रहों का एक सभ्य प्रबंधन है।

तो मानचित्र को फिर से शुरू करने का सबसे सुविधाजनक तरीका यह है:

<#list tags>
<ul class="posts">
    <#items as tagName, tagCount>
        <li>{$tagName} (${tagCount})</li>
    </#items>
</ul>
<#else>
    <p>No tags found.</p>
</#list>

अब और नहीं <#if ...> रैपर।


0
2017-07-23 16:09