问题
I want to create dynamic dialog windows by using <ui:repeat>
and <p:dialog>
with <ui:include>
. But there's an exception when I tried like below.
main.xhtml
<p:outputPanel id="windowsPanel" layout="block" style="width:100%;">
<p:outputPanel rendered="#{mainView.dynamicWindows ne null}">
<ui:repeat var="item" value="#{mainView.dynamicWindows}">
<p:dialog binding="#{item.dialog}">
<ui:include src="#{item.includedWindowPath}" />
</p:dialog>
</ui:repeat>
</p:outputPanel>
</p:outputPanel>
MainView.java
@ManagedBean(name = "mainView")
@SessionScoped
public class MainView extends BaseView {
private static final long serialVersionUID = -6291834350102049312L;
private List<Window> dynamicWindows;
@PostConstruct
public void init() {
fillWindows();
}
private void fillWindows() {
dynamicWindows = new ArrayList<Window>();
for (int i = 0; i < 3; i++) {
Window window = new Window("Header " + i);
window.getDialog().setId("_dynamicWindow" + i);
window.getDialog().setWidgetVar("_dynamicWindowWidget" + i);
dynamicWindows.add(window);
}
}
// getters & setters
The exception:
javax.servlet.ServletException: /main.xhtml @33,42 binding="#{item.dialog}": Target Unreachable, identifier 'item' resolved to null
javax.faces.webapp.FacesServlet.service(FacesServlet.java:422)
org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
回答1:
The <ui:include>
is a tag handler which runs during view build time, while the <ui:repeat>
is an UI component which runs during view render time. Tag handlers produces the JSF UI component tree. JSF UI components produces HTML. They do not run in sync.
So, when the <ui:include>
runs, the #{item}
which is specified by <ui:repeat var>
is simply not available in the scope, because the <ui:repeat>
hasn't run at that time. You need an iterating tag handler instead of an iterating JSF UI component. The JSTL <c:forEach>
is such one. Replacing <ui:repeat>
by <c:forEach>
should fix this issue. It may however have undesireable side effects. It's hard to tell beforehand as your concrete functional requirements are not fully clear.
See also:
- JSTL in JSF2 Facelets... makes sense? (discusses lifecycle of tag handlers vs UI components)
回答2:
If you have say a limited no of cases (say for e.g 4-5 cases) to dynamically choose from & include for an item within ui:repeat
then it may be worth doing it this way, as it would save you from building huge component trees with c:forEach
if your list to iterate is bigger. This'll conditionally just render one out of several cases to include xhtml from. These cases wont be repeated multiple times in the component tree, for each time in your list. Hopefully, this should give better performance & also save from concerns of mixing JSF with JSTL.
<ui:repeat var="item" value="#{mainView.dynamicWindows}">
<h:panelGroup rendered="#{booleancase1}">
<ui:include src="case1.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{booleancase2}">
<ui:include src="case2.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{booleancase3}">
<ui:include src="case3.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{booleancase4}">
<ui:include src="case4.xhtml" />
</h:panelGroup>
</ui:repeat>
来源:https://stackoverflow.com/questions/9603233/using-dynamic-uiinclude-inside-uirepeat-results-in-nullpointerexception