Ответ 1
Изменить: Больше не использовать это решение, особенно не .get(prop)
. См. Другие ответы.
Вы используете встроенную функцию функции, например. это должно работать:
<#list user?keys as prop>
${prop} = ${user.get(prop)}
</#list>
Freemarker имеет два типа данных коллекции, списки и хэшмапы Есть ли способ перебрать ключи hashmap так же, как мы делаем со списками?
Итак, если у меня есть var с данными, скажем:
user : {
name : "user"
email : "[email protected]"
homepage : "http://nosuchpage.org"
}
Я хотел бы напечатать все свойства пользователя с их значением. Это неверно, но цель понятна:
<#list user.props() as prop>
${prop} = ${user.get(prop)}
</#list>
Изменить: Больше не использовать это решение, особенно не .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.SAFE или Expose.ALL, тогда может использоваться стандартный Java-подход к итерации набора записей:
Например, во Фримаркере (начиная с версии 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.
Если вы установили Map на 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