Soru Freemarker, hashmap anahtarları üzerinde yineleniyor


Freemarker'ın iki koleksiyon veri türü, listeleri ve hashmapları var Listelerde yaptığımız gibi hashmap anahtarlarının üzerinde yinelemenin bir yolu var mı?

Yani verilerle bir varsam şunu söyleyelim:

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

Tüm kullanıcının özelliklerini kendi değerleriyle yazdırmak istiyorum. Bu geçersiz, ancak hedef belli:

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

76
2017-09-30 12:22


Menşei




Cevaplar:


Düzenle: Bu çözümü FreeMarker 2.3.25 ve üstü ile kullanmayın, özellikle de .get(prop). Diğer cevapları gör.

Yerleşik kullanıyorsunuz anahtarlar işlev, ör. bu çalışmalı:

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

94
2017-09-30 12:27



sözdizimi, cevabımda yayınladığım bağlantıda gösterildiği gibi en son sürümde farklıdır. Bunun eski bir soru olduğunu anlıyorum, ancak Google’da yüksek puan alıyor. - Nick Spacek
sadece bir not - kullanabilirsiniz ${user[prop]} kestirme olarak - Bozho
Bu bir performans sızıntısıdır: her anahtar için değeri geri alması gerekir. EntrySet () üzerinde yinelenen bu sorun yok. - Geoffrey De Smet
$ {user [prop]} olmalı - dns
$ {Map [key]} var freemarker.org/docs/ref_builtins_hash.html - david_p


FYI, değerleri almak için sözdizimi gibi görünüyor aşağıdaki gibi:

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



Bu sözdizimi nasıl farklı? - Parker
Artık işe yaramadığını düşünüyorum. - Nick Spacek
iyi cevap ;-), değeri yazdırırken null için bir kontrol yapmanız gerekebilir, <#if h [key] ??> $ {key} = $ {h [key]}; </ # If> - Brad Parks
Sözdizimi değişmedi. Her ikisi de [key] ve .get(key) eski zamanlardan beri var. .get(key) FTL için özel değil, sadece bu genel Java yöntemini çağırıyor. Ancak, sadece FreeMarker ifşa edecek şekilde yapılandırılmışsa kullanabilirsiniz. Map yöntemleri. - ddekany
Yinelemeye başladığımda, (getClass, hashCode, eşittir, get, toString, class) yöntemleri alırım ... ancak, 'id' gibi özelliklerden hiçbirini görmek istemiyorum. Herhangi bir öneri, bu karma olmayan yöntem listesinin listesini nasıl alabilirim? Bu mülk adlarını bilmem gerek. : | - MaxRocket


2.3.25'ten beri bunu yapın:

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

Bu aynı zamanda dize olmayan anahtarlarla da çalıştığını unutmayın ( map[key]olarak yazılması gereken map?api.get(key) sonra).

2.3.25'ten önce standart çözüm:

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

Ancak, bazı eski FreeMarker entegrasyonları, genel olarak garip bir yapılandırma kullanır. Map yöntemler (gibi getClass) tuşlar olarak görünür. Saf kullanıyorlar gibi oluyor. BeansWrapper (yerine DefaultObjectWrapper) kimin simpleMapWrapper mülk üzerinde kaldı false. Yöntemleri gerçek ile karıştırdığı için böyle bir kurulumdan kaçınmalısınız. Map girdileri. Ama böyle talihsiz bir kuruma girerseniz, durumdan kaçma yolu, aşağıdaki gibi açık Java yöntemlerini kullanmaktır. user.entrySet(), user.get(key)vb. gibi şablon dil yapılarını kullanmamak ?keys veya user[key].


24
2017-07-08 17:25



Bu mükemmel çalışıyor. Ancak, springsource IDE'de hatalar görüyorum. Nasıl düzeltileceği hakkında bir fikrin var mı? Teşekkürler - harshavmb
@harshavmb Hangi hatalar? Eski bir FreeMarker sürümü olan belki de eski bir FreeMarker eklentisi kullanıyor mu? - ddekany
Düşünme. En son jboss araçlarından indirdik. Diğer makineyi deneyeceğim ve bilmene izin vereceğim. - harshavmb
@harshavmb gibi bir şey girerseniz ${x?nosuchthing} ve bunun üzerine gelin, gösterilen hata mesajı hangi FreeMarker sürümünü kullandığını gösterir. Olmalı 2.3.25-incubating. - ddekany
Garip, sadece Mac'de denedim ve sorunu kopyalayamadım. Sorun sadece benim vm ile görünüyor. Kavanoz versiyonuna bir göz atacağım. Ancak, editörde sadece bir hatadır, ancak kod doğru bir şekilde yürütüldü. - harshavmb


Kullanıyorsanız BeansWrapper Expose.SAFE veya Expose.ALL'ın bir pozlama seviyesi ile, giriş kümesini yinelemek için standart Java yaklaşımı kullanılabilir:

Örneğin, aşağıdakiler Freemarker'da çalışacaktır (en azından 2.3.19 sürümünden itibaren):

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

Örneğin Struts2’de BeanWrapper bir uzantısı Bu iterasyona izin vermek için varsayılan poz seviyesiyle kullanılır.


12
2018-05-07 14:48



Bunu gerçekten denedin mi? Çünkü benim bir InvalidReferenceException denediğimde, map?keys çalıştı. - kdgregory
Bu sadece kullanımda çalışır freemarker.ext.beans.BeansWrapper nesne sarıcı olarak. Aksi takdirde Maps otomatik olarak bir SimpleHash desteklemeyen nesne #entrySet(). (görmek freemarker.sourceforge.net/docs/api/freemarker/template/...) - Koraktor
Doğru ve cevabınızı yorumunuzu yansıtacak şekilde güncelledim. İyi gözüküyor! - rees
Yukarıdakiler, SpringWaremver çözücüyü BeanWrapper ile kullanıyorsanız, FTL'nin içinde yaratılan karma için işe yaramayacaktır. Ftl dosyası içinde bildirilen karma paketlenmiş değildir ve hala? Tuşları kullanılarak yinelenen bir tekrarlama olacaktır. - skipy
Saf kullanmayın BeansWrapperen azından varsayılanlarıyla değil simpleMapWrapper olduğu false. Tuşları yöntem isimleriyle karıştırdığı için çok kafa karıştırıcı olur. Eğer araman gerekiyorsa entrySet(), varsayılan olan gibi bir "temiz" nesne sarıcı kullanmaya devam edin ve yazın map?api.entrySet() Anahtarlar yerine Java API'sine erişmeniz gerekiyorsa. - ddekany


Yinelenen Nesneler

Harita anahtarlarınız bir dize ve bir dize değilse, Freemarker'ı kullanarak yineleyebilirsiniz.

1) Haritayı denetleyicideki bir listeye dönüştürün:

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

2) Haritayı Freemarker şablonunda yineleyin, Anahtardaki nesneyi ve Değerde Nesne'ye ulaşın:

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

2
2018-06-20 08:42





Java programınızda ayarladığınız anahtara erişmek için tek bir teklif kullanabilirsiniz.

Java’daki bir haritayı bu şekilde ayarlarsanız

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

Sonra Freemarker'daki 'hash' üyelerine bu şekilde erişebilirsiniz -

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

Çıktı :

a
b

1
2018-03-19 18:28



Bu, tek tek tuşların nasıl ele alınacağını gösterir, ancak soru nasıl yineleneceğini sorar. - Lambart


Tamlık için, yakın zamanda Freemarker'da boş koleksiyonların iyi bir şekilde ele alınmasından söz edilmeye değer.

Bir haritayı tekrarlamak için en uygun yol:

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

Daha fazla yok <#if ...> sarmalayıcıları.


0
2017-07-23 16:09