Reputation: 8809
A page/bean of mine has its preRenderView
event fired twice on the first page load then 2 + n
times for each postback, where n
is the number of postbacks (including the current one) that have occurred.
After reading a few other posts here, I moved <f:event type="preRenderView" listener="myBean.preRenderView"/>
outside of <f:metadata/>
and that reduced the number of preRenderView
calls by one. That is, it is called once on the full page load and 1 + n
times for each postback. I even tried to move the <f:event/>
tag outside of <f:view/>
, but it had no effect.
I'm not sure if this is relevant: The page uses a template:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:fb="http://www.facebook.com/2008/fbml">
<f:view contentType="text/html">
<ui:insert name="metadata"/>
<h:head>
<!-- Some stuff here -->
<ui:insert name="content"/>
<!-- More stuff here -->
</h:head>
<h:body>
</h:body>
</f:view>
</html>
And the relevant bits of the page:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title></title>
</h:head>
<h:body>
<ui:composition template="/WEB-INF/templates/myLayout.xhtml">
<ui:define name="windowTitle">My Page</ui:define>
<ui:define name="metadata">
<f:event type="preRenderView" listener="#{myBean.preRenderView}"/>
</ui:define>
<ui:define name="content">
<!-- Some content here -->
<h:panelGroup id="reRenderable" layout="block">
<!-- More content here -->
<h:form prependId="false">
<h:outputLabel for="mySelector" value="Item:"/>
<h:selectOneMenu id="mySelector"
value="#{myBean.item}"
converter="#{myConverter}"
validator="#{itemActiveValidator.validate}">
<f:selectItems value="#{myBean.myItems}"/>
<f:ajax render=":reRenderable"/>
</h:selectOneMenu>
</h:form>
<!-- More content here -->
</h:panelGroup>
<!-- More content here -->
</ui:define>
</ui:composition>
</h:body>
</html>
Upvotes: 5
Views: 8402
Reputation: 329
Try this. I don' t know tecnical differences between your code and mine below. I changed <ui:insert name="content"/>
location to between body tags from head tags. And add f:metadata
.
But when I use like this this does not call twice. Works fine. it can be about page structure. Maybe about using html tag twice. You need one. But complete pages missing parts, only missing parts with composition blocks.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:fb="http://www.facebook.com/2008/fbml">
<f:view contentType="text/html">
<f:metadata>
<ui:insert name="metadata"/>
</f:metadata>
<h:body>
<!-- Some stuff here -->
<ui:insert name="content"/>
<!-- More stuff here -->
</h:body>
</f:view>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="/WEB-INF/templates/myLayout.xhtml">
<ui:define name="windowTitle">My Page</ui:define>
<ui:define name="metadata">
<f:event type="preRenderView" listener="#{myBean.preRenderView}"/>
</ui:define>
<ui:define name="content">
<!-- Some content here -->
<h:panelGroup id="reRenderable" layout="block">
<!-- More content here -->
<h:form prependId="false">
<h:outputLabel for="mySelector" value="Item:"/>
<h:selectOneMenu id="mySelector"
value="#{myBean.item}"
converter="#{myConverter}"
validator="#{itemActiveValidator.validate}">
<f:selectItems value="#{myBean.myItems}"/>
<f:ajax render=":reRenderable"/>
</h:selectOneMenu>
</h:form>
<!-- More content here -->
</h:panelGroup>
<!-- More content here -->
</ui:define>
</ui:composition>
Upvotes: -1
Reputation: 329
try
@ManagedBean
@XScoped --sessionScope,viewScope
Public class MyRecordsBean{
public void preRenderView(){
if (!FacesContext.getCurrentInstance().isPostback(){
//put initView codes here
}
}
Upvotes: -1
Reputation: 8809
It looks like yet another Mojarra bug: JAVASERVERFACES-2162
I applied the workaround as follows and it works:
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="dummy"/>
<f:event type="preRenderView" listener="#{myRecordsBean.preRenderView}"/>
</f:metadata>
</ui:define>
All that's left to do is push dummy
up to the template to keep the pages that use it free from this filth.
Upvotes: 5