Freemarker итерации по ключам hashmap


Freemarker имеет два типа данных коллекции, списки и хэш-карты Есть ли способ перебирать ключи hashmap так же, как мы делаем со списками?

поэтому, если у меня есть var с данными, скажем:

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

Я хотел бы распечатать все свойства пользователя с их значением. Это неверно, но цель ясна:

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

7 ответов:

Edit: Не используйте это решение с FreeMarker 2.3.25 и выше, особенно не .get(prop). См. другие ответы.

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

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

FYI, похоже, что синтаксис для извлечения значений изменился в соответствии с:

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>

начиная с 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>

однако некоторые действительно старые интеграции FreeMarker используют странную конфигурацию, где публика Map методы (например,getClass) появляются как ключи. Это происходит, как они используют чистый BeansWrapper (вместо DefaultObjectWrapper), чьи simpleMapWrapper имущество было оставлено на false. Вам следует избегать такой настройки, так как она смешивает методы с реальными Map записи. Но если вы столкнетесь с такой неудачной установкой, способ избежать ситуации-использовать открытые методы Java, такие как user.entrySet(),user.get(key) и т. д., и не используя языковые конструкции шаблона, такие как ?keys или user[key].

при использовании BeansWrapper С уровнем экспозиции Expose.Безопасно или разоблачить.Все, тогда можно использовать стандартный подход Java к итерации набора записей:

например, в Freemarker будет работать следующее (Начиная как минимум с версии 2.3.19):

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

в Struts2, например, расширение BeanWrapper используется с уровнем экспозиции по умолчанию, чтобы разрешить этот способ итерации.

Переборе Объектов

если ваши ключи карты-это объект, а не строка, вы можете повторить его с помощью Freemarker.

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>

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

Если вы установите карту в Java, как это

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

тогда вы можете получить доступ к членам "хэш" в Freemarker, как это -

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

выход :

a
b

для полноты картины стоит отметить, что с недавнего времени в Freemarker есть приличная обработка пустых коллекций.

таким образом, наиболее удобный способ итерации карты:

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

не больше <#if ...> фантики.