c:for ui:repeat中的每个素面(例如p:panelgrid) [英] c:forEach inside primefaces(e.g. p:panelgrid) inside ui:repeat
问题描述
我必须动态地产生一个表列表.每一个都有可变数量的列(具有固定的行).
要执行此操作,我首先将<p:panelGrid>
放在<ui:repeat>
内:这样我就正确地生成了一个表列表.
然后,为了动态生成列,我尝试将<ui:repeat>
或<c:forEach>
都放在<p:panelGrid>
内.结果我没有得到任何行.
我在这里写了一个最小的例子.在bean testBackingBean
中,我定义(并初始化了)变量ArrayList<ArrayList<String>> tables
.这是无法产生预期结果的xhtml:
<ui:repeat var="table" value="#{testBackingBean.tables}">
<p:panelGrid>
<f:facet name="header">
<p:row>
<p:column >header of #{table}</p:column>
</p:row>
</f:facet>
<p:row>
<c:forEach var="row" items="${table}">
<p:column>#{row}</p:column>
</c:forEach>
</p:row>
</p:panelGrid>
</ui:repeat>
值得注意的是,标题行正确地将#{table}
转换为字符串.问题是我看不到任何数据行.
此外,如果我使用<table>
而不是<p:panelGrid>
,一切都会按预期进行.
此外,我尝试了<c:forEach>
和<ui:repeat>
的不同排列,但没有成功.
那么,我该如何动态地生成更多的表(使用素面)并设置出数量惊人的列呢?
谢谢!
我想使用两个<c:forEach>
,但是即使只有一个<c:forEach>
,我也会得到一个空结果.实际上,如果我尝试以下xhtml:
<c:forEach items="${testBackingBean.tables}" var="tabella">
current element: #{tabella}
</c:forEach>
然后我得到一个空结果. (我知道,这是一个不同的问题)
从XHTML源代码到生成的HTML输出的过渡是一个两步过程.
-
首先,在视图构建期间,将解析XHTML源代码并将其转换成Java实例树,该树代表JSF UI组件树,由
FacesContext#getViewRoot()
提供. -
然后,在视图渲染期间,JSF UI组件树会生成HTML输出,并从
UIViewRoot#encodeAll()
方法开始将其写入HTTP重新操作.
Taghandlers 像所有JSTL <c:xxx>
标记,几个JSF <f:xxx>
标记和仅几个Facelets <ui:xxx>
标记在视图构建期间运行. UI组件像所有JSF <h:xxx>
标签,多个Facelets <ui:xxx>
标签和仅几个JSF <f:xxx>
标签在视图渲染期间运行.
换句话说,在视图构建期间,基于<c:forEach items>
在<c:forEach>
内部声明的UI组件在JSF组件树中被多次重新创建,这些反过来又分别在视图渲染期间生成各自的HTML输出.在<ui:repeat>
内部声明的UI组件在视图构建期间仅在JSF组件树中创建一次,然后根据<ui:repeat value>
多次重用以在视图呈现期间生成HTML输出.
您的具体问题是由以下事实引起的:<ui:repeat var="table">
仅在视图渲染期间可用,而在视图构建期间不可用. <c:forEach>
基本上是在视图构建期间将要运行的#{null}
作为值检索的.
您可以通过将外部<ui:repeat>
替换为<c:forEach>
来解决此问题.尽管我不知道您是否能更好地使用<ui:repeat><p:dataTable><p:columns>
来代替.
另请参见:
I have to dinamically produce a list of tables. Each of these have a variable number of columns (with fixed rows).
To perform this I first put a <p:panelGrid>
inside an <ui:repeat>
: so I correctly produced a list of tables.
Then, to dinamically produce the columns, I tried put both an <ui:repeat>
or a <c:forEach>
inside the <p:panelGrid>
. In the result I obtain no rows.
I written a minimal example here. In the bean testBackingBean
, I have defined (and initialized) the variable ArrayList<ArrayList<String>> tables
. This is the xhtml that does not produce the expected results:
<ui:repeat var="table" value="#{testBackingBean.tables}">
<p:panelGrid>
<f:facet name="header">
<p:row>
<p:column >header of #{table}</p:column>
</p:row>
</f:facet>
<p:row>
<c:forEach var="row" items="${table}">
<p:column>#{row}</p:column>
</c:forEach>
</p:row>
</p:panelGrid>
</ui:repeat>
Noteworthy the header-row correctly converts #{table}
into string. The problem is that I see no rows of data.
Also, if I use the <table>
instead of the <p:panelGrid>
everything work as excpected.
Also, I tried different permutations of <c:forEach>
and <ui:repeat>
with no succes.
So, how can I dinamically produce more tables (using prime-faces) and set a dinamical number of columns?
Thanks!
EDIT: I would like to use two <c:forEach>
, but even with one only <c:forEach>
I get an empty result. In fact if I try the following xhtml:
<c:forEach items="${testBackingBean.tables}" var="tabella">
current element: #{tabella}
</c:forEach>
then I get an empty result. (I know,this is a different question)
The transition from the XHTML source code to the generated HTML output is a two-step process.
First, during view build time, the XHTML source code is parsed and turned in a tree of Java
UIComponent
instances representing the JSF UI component tree, as available byFacesContext#getViewRoot()
.Then, during view render time, the JSF UI component tree produces HTML output and writes it to the HTTP resopnse, starting with
UIViewRoot#encodeAll()
method.
Taghandlers like all JSTL <c:xxx>
tags, several JSF <f:xxx>
tags and only a few Facelets <ui:xxx>
tags run during view build time. UI components like all JSF <h:xxx>
tags, several Facelets <ui:xxx>
tags and only a few JSF <f:xxx>
tags run during view render time.
The <c:forEach>
is a taghandler and the <ui:repeat>
is an UI component.
In other words, the UI components which are declared inside <c:forEach>
are recreated multiple times in the JSF component tree based on <c:forEach items>
during view build time which in turn individually produce each their own HTML output during view render time. The UI components which are declared inside <ui:repeat>
are created only once in the JSF component tree during view build time which in turn are reused multiple times based on <ui:repeat value>
to produce HTML output during view render time.
Your concrete problem is caused by the fact that <ui:repeat var="table">
is only available during view render time, not during view build time. The <c:forEach>
is basically retrieving a #{null}
as value when it's about to run during view build time.
You can solve this by replacing the outer <ui:repeat>
by <c:forEach>
. Although I wonder if you couldn't better use <ui:repeat><p:dataTable><p:columns>
instead.
See also:
这篇关于c:for ui:repeat中的每个素面(例如p:panelgrid)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!