我们正在做一个学校项目,突然发现一个重复性很高的任务,我们决定从中制作一个 partialView。它基本上是一个表,由保存在 @Named
和 @SessionScoped
(均为 CDI)bean
中的列表编译而成。
partialView.xhtml代码:
<ui:composition>
<h:dataTable
/* Style */>
<c:forEach items="#{playListVM.playList.songs}" var="song">
<f:facet name="caption">
#{playListVM.playList.name}
</f:facet>
<h:column>
<f:facet name="header">Index</f:facet>
#{playListVM.playList.songs.indexOf(song)+1}
</h:column>
...
我想像这样多次调用这个“方法”:
home.xhtml的代码:
<c:forEach items="#{c.playLists}" var="playList">
<ui:include src="#{c.playListPV(playList)}" />
</c:forEach>
playListPV(playlist)
将 playListVM.playList
的值设置为 playList
并返回 path
到.xhtml 文件。
首先,我们只使用 h:dataTable
进行了尝试,只要我们每次渲染使用一次 partialView 就可以正常工作(否则它使用相同的引用并且每个 PV 都是相同的)。所以我在谷歌上搜索了更多,发现我每次调用该方法时都会覆盖该对象。然后我阅读了这篇关于 c:forEach
和渲染顺序的文章。我们到了。
到目前为止,我认为整个方法是错误的...
请您参考如下方法:
我了解到您最初是这样尝试的:
<h:dataTable value="#{c.playLists}" var="playList">
<ui:include src="#{c.playListPV(playList)}" />
</h:dataTable>
这确实不会按您预期的方式工作。 <ui:include>
在 View 构建期间作为标记处理程序运行,而 <h:dataTable>
在 View 呈现时间期间作为 UI 组件运行,在 View 构建时间之后。所以,此刻 <ui:include>
运行,#{playList}
未在范围内设置。实际上,您最终得到一个包含其 src
的包含等于 c.getPlayListPV(null)
.
您需要创建多个 <ui:include>
而不是在 View 构建期间。您应该使用在 View 构建期间运行的迭代标签处理程序。 JSTL <c:forEach>
确实是这样的。为了使代码更清晰,transform the include file into a tag file .
也就是说,术语“部分 View ”在 JSF 中的含义与您的想法完全不同。这与<ui:include>
无关.术语“部分 View ”涉及在部分请求期间正在处理的 View 部分(即,它正是 <f:ajax execute>
和 <f:ajax render>
涵盖的那些组件)。