【问题标题】:Tapestry loop through nested map in tml fileTapestry 循环遍历 tml 文件中的嵌套映射
【发布时间】:2014-02-27 01:33:22
【问题描述】:

我有以下地图

Map<String, Map<String, Long>>

此地图可通过java文件中的以下方法访问。

public List<Entry<String, List<Entry<String, Long>>>> getByEventTypeSorted() {
    List<Entry<String, List<Entry<String, Long>>>> ret = new ArrayList<Entry<String, List<Entry<String, Long>>>>();
    ret.addAll((Collection<? extends Entry<String, List<Entry<String, Long>>>>) byEventType.entrySet());
    return ret;
}

因此,我将Map&lt;String, Map&lt;String, Long&gt;&gt; 转换为List&lt;Entry&lt;String, List&lt;Entry&lt;String, Long&gt;&gt;&gt;&gt; 并返回它。

现在,在我的 tml 文件中,我试图像这样循环遍历它。

<tr t:type="Loop" t:source="summarizer.byEventTypeSorted" t:value="entry">
    <td style="border: 1px solid #EEEEEE; padding: 3px">${entry.key}</td>
    <td style="border: 1px solid #EEEEEE; padding: 3px" t:type="Loop" t:source="${entry.value}" t:value="entry2"> 
        ${entry2.key}
    </td>
</tr>

对应的java文件有以下属性。

@Property
private Entry<String,Long> entry;
@Property
private Entry<String,Long> entry2;

当我运行上面的代码时。产生以下异常。

Failure writing parameter 'value' of component ConceptSummaries:loop_1: Could not find a coercion from type java.lang.String to type java.util.Map$Entry.

如果我在 java 文件中将属性 entry2 的类型更改为字符串,如下所示.....

@Property
private Entry<String,Long> entry;
@Property
private String entry2;

然后在 tml 文件中循环,如下所示。

<tr t:type="Loop" t:source="summarizer.byEventTypeSorted" t:value="entry">
    <td style="border: 1px solid #EEEEEE; padding: 3px">${entry.key}</td>
    <td style="border: 1px solid #EEEEEE; padding: 3px" t:type="Loop" t:source="${entry.value}" t:value="entry2"> 
        ${entry2}
    </td>
</tr>

然后我将整个列表呈现为单个字符串。

这意味着 Tapestry 正在将 List&lt;Entry&lt;String, Long&gt;&gt; 转换为字符串。 我不希望这种情况发生,因为我想遍历列表并访问各个条目。

如何循环遍历这些嵌套的地图?还有有什么办法可以保留inner list的类型,防止tapestry转成字符串?

更新: 我能够使用 Lance Java 的建议解决这个问题。以下是详细信息。

tml 文件中的代码。

<tr t:type="Loop" t:source="summarizer.byEventTypeSorted.entrySet()" t:value="entry">
    <td style="border: 1px solid #EEEEEE; padding: 3px">${entry.key}</td>
    <td style="border: 1px solid #EEEEEE; padding: 3px" t:type="Loop" t:source="KeySetForEntryValue" t:value="entry2"> 
        ${entry2.key}
    </td>
</tr>

我在对应的 java 类中有 "KeySetForEntryValue"Map&lt;String, Map&lt;String, Long&gt;&gt; 的 getter 方法。

public Set<Entry<String, Long>> getKeySetForEntryValue(){
    return entry.getValue().entrySet();
}

public Map<String, Map<String, Long>> getByEventTypeSorted() {
    return byEventType;
}

以下是同一个java类中的属性。

@Property
private Entry<String, Map<String, Long>> entry;
@Property
private Entry<String, Long> entry2;

【问题讨论】:

  • 你不需要转换成List,因为循环可以迭代java.util.Collection

标签: java list loops map tapestry


【解决方案1】:

你的问题是t:source="${entry.value}"

在模板属性中使用 ${...} 会导致字符串的值为 coerced

改用t:source="entry.value"

我会这样做:

@Property
private Map<String, Map<String, Long>> byEventType;

@Property
private Entry<String, Map<String, Long>> entry;

@Property
private Entry<String, Long> entry2;

<tr t:type="Loop" t:source="byEventType.entrySet()" t:value="entry">
<td style="border: 1px solid #EEEEEE; padding: 3px">${entry.key}</td>
<td style="border: 1px solid #EEEEEE; padding: 3px" t:type="Loop" t:source="entry.value.entrySet()" t:value="entry2"> 
    ${entry2.key} = ${entry2.value}
</td>

【讨论】:

  • 感谢您的回答。我一直在尝试使用您的建议使我的代码正常工作。当上面的代码运行时,你会得到一个异常。 '无法将'entry.value.keySet()'转换为组件参数绑定:表达式'entry.value.keySet()'的异常生成管道:类java.lang.Object中没有公共方法'keySet()'。 '我现在正在阅读类型强制以找出问题所在。
  • 也许tapestry的属性表达式解析器跟不上泛型。在这种情况下,您可以将 entry.value.keySet() 提取到 getter 并调用它。
  • 是的,我从 java 类中的 getter 方法返回了 entry.value.entrySet(),因为问题是在 tml 文件的内部循环中无法访问 entrySet() 方法。现在可以了。再次感谢!我已经更新了我的答案,以适应可以解决问题的更改。
猜你喜欢
  • 1970-01-01
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2021-11-20
  • 2011-01-09
  • 2018-02-11
相关资源
最近更新 更多