Tengo una página web que incluye una página secundaria que cambia según el elemento que elijo en el menú de la base de datos (ui:include
). Algunas páginas secundarias incluyen un componente compuesto personalizado que implementé. La primera página que muestra la aplicación web tiene todos sus oyentes trabajando correctamente. Cuando cambio la página secundaria a través del menú de base, los oyentes de VideoStatusTable (oyentes del componente compuesto) no funcionarán hasta que actualice la página en el navegador (con F5) O si selecciono la página nuevamente en el menú de base.Oyentes de componente compuesto que solo funcionan después de la recarga de la página
Aquí está la página principal que contiene el menú de la base.
<h:body style="width:100%;height:100%;position:relative;">
<h:panelGroup id="contentPanelGroup">
<ui:include src="#{Template.currentView.view}" />
</h:panelGroup>
<div id="header-wrapper">
<h:form id="headerForm" styleClass="titleSize" style="position:relative;height:100%;width:100%;">
</h:form>
</div>
<div id="footer-wrapper">
<h:form id="footerForm">
<h:graphicImage name="ctec.png" library="images" style="position:absolute;left:30px;bottom:10px;"/>
<p:dock>
<p:menuitem value="#{msgs.ViewEnum_TRANSFER}" icon="#{resource['images:hard-drive-download.png']}" action="#{Template.setWindow(0)}" update=":contentPanelGroup :headerForm :msgsArea" />
<p:menuitem value="#{msgs.ViewEnum_STATUS}" icon="#{resource['images:gears.png']}" action="#{Template.setWindow(1)}" update=":contentPanelGroup :headerForm :msgsArea"/>
<p:menuitem value="#{msgs.ViewEnum_ORGANIZATION}" icon="#{resource['images:folder.png']}" action="#{Template.setWindow(2)}" update=":contentPanelGroup :headerForm :msgsArea" />
<p:menuitem value="#{msgs.ViewEnum_VALIDATION}" icon="#{resource['images:chart-bar.png']}" action="#{Template.setWindow(3)}" update=":contentPanelGroup :headerForm :msgsArea" />
<p:menuitem value="#{msgs.ViewEnum_REPORT}" icon="#{resource['images:documents.png']}" action="#{Template.setWindow(4)}" update=":contentPanelGroup :headerForm :msgsArea" />
</p:dock>
</h:form>
</div>
<p:growl id="msgsArea" life="5000"/>
<ui:debug/>
</h:body>
TemplateBean
se parece a esto:
@Named(value="Template") // CDI
@SessionScoped // CDI
public class TemplateBean implements Serializable {
private static final long serialVersionUID = -8230221469543897876L;
private Integer window = 2;
// Some getters ...
// Get Window
public Integer getWindow() {
return window;
}
public void setWindow(Integer window) {
this.window = window;
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(FacesMessage.SEVERITY_INFO, getCurrentViewTitle(), getCurrentViewTitle())
);
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(FacesMessage.SEVERITY_ERROR, getCurrentViewTitle(), getCurrentViewTitle())
);
}
}
ViewEnum
(que se utiliza para la elección de qué se muestra la vista):
public enum ViewEnum {
TRANSFER ("hard-drive-download.png", "/private/VideoTransfer.xhtml"),
STATUS ("gears.png", "/private/ProcessStatus.xhtml"),
ORGANIZATION ("folder.png", "/private/DataOrganization.xhtml"),
VALIDATION ("chart-bar.png", "/private/ProcessValidation.xhtml"),
REPORT ("documents.png", "/private/ReportGeneration.xhtml"),
;
private String iconFileName;
private String view;
private StreamedContent icon = null;
private ViewEnum(String iconFileName, String view) {
this.iconFileName = iconFileName;
this.view = view;
}
public String getIconFileName() {
return this.iconFileName;
}
public String getTranslationKey() {
return "ViewEnum_" + this.toString();
}
public StreamedContent getIcon() {
// irrelevant code ...
}
public String getView() {
return this.view;
}
}
El componente personalizado:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:cmpnt="http://java.sun.com/jsf/composite/component">
<composite:interface componentType="videoStatusTableComponent">
<composite:attribute name="value" required="true"/>
<composite:attribute name="selection" required="true"/>
<composite:attribute name="selectionListener" required="true" method-signature="void listener(org.primefaces.event.SelectEvent)"/>
<composite:attribute name="selectionUpdate" required="false" default="@this"/>
<composite:attribute name="refreshListener" required="true" method-signature="void action()"/>
</composite:interface>
<composite:implementation>
<p:dataTable id="cmpntVideoList" var="video" value="#{cc.attrs.value}" rowKey="#{video.key}" style="clear:both;"
selection="#{cc.attrs.selection}" selectionMode="single" emptyMessage="#{cc.attrs.emptyValueListMsg}">
<p:ajax event="rowSelect" listener="${cc.selectionListener}" process="@this" update="${cc.attrs.selectionUpdate}"/>
<composite:insertFacet name="header"/>
<p:column headerText="Test">
#{video.humanReadableVideoId}
</p:column>
<f:facet name="footer">
<h:commandLink action="${cc.attrs.refreshListener}" style="float:right;">
<h:graphicImage library="images" name="button-rotate-cw_16.png"/>
<f:ajax render="cmpntVideoList" execute="@this"/>
</h:commandLink>
</f:facet>
</p:dataTable>
</composite:implementation>
</html>
@FacesComponent("videoStatusTableComponent")
public class VideoStatusTableComponent extends UINamingContainer {
public void selectionListener(org.primefaces.event.SelectEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
MethodExpression ajaxEventListener = (MethodExpression) getAttributes().get("selectionListener");
ajaxEventListener.invoke(context.getELContext(), new Object[] { event });
}
}
El primer sub-página (y su Bean), que incluye el componente:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:cmpnt="http://java.sun.com/jsf/composite/component">
<ui:composition>
<h:form id="contentForm">
<cmpnt:videoStatusTable id="transferingVideoList"
value="#{videoTransfer.tableModel}"
selection="#{videoTransfer.selectedTableReadyNotCompletelyTranferedVideo}"
selectionListener="${videoTransfer.onVideoSelection}"
selectionUpdate=":msgsArea"
refreshListener="${processStatus.refreshUncompletedVideos}"
>
</cmpnt:videoStatusTable>
</h:form>
</ui:composition>
</html>
@Named(value="videoTransfer") // CDI
@SessionScoped // CDI
public class VideoTransferBean implements Serializable {
private static final long serialVersionUID = -9019701853654362317L;
private VideoStatus selectedTableReadyNotCompletelyTranferedVideo;
private VideoStatusTableModel tableModel;
private List<Video> currentlyTranferingVideos = null;
// Other irrelevant code...
public VideoStatusTableModel getTableModel() {
return tableModel;
}
public void setSelectedTableReadyNotCompletelyTranferedVideo(VideoStatus selectedTableReadyNotCompletelyTranferedVideo) {
this.selectedTableReadyNotCompletelyTranferedVideo = selectedTableReadyNotCompletelyTranferedVideo;
}
public VideoStatus getSelectedTableReadyNotCompletelyTranferedVideo() {
return selectedTableReadyNotCompletelyTranferedVideo;
}
public void onVideoSelection(SelectEvent event) {
FacesMessage msg = new FacesMessage("Video Selected: " + ((VideoStatus) event.getObject()).getHumanReadableVideoId());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
Otra sub-página que incluye el mismo componente (en este caso los oyentes no funcionan hasta que vuelva a cargar la página (a través de la dársena o si golpeo F5)):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<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"
xmlns:p="http://primefaces.org/ui"
xmlns:cmpnt="http://java.sun.com/jsf/composite/component"
>
<ui:composition>
<h:form id="contentForm">
<cmpnt:videoStatusTable
id="orphanVideoList"
value="#{DataOrganization.videoTableModel}"
selection="#{DataOrganization.selectedVideo}"
selectionListener="#{DataOrganization.onOrphanVideoSelection}"
selectionUpdate=":msgsArea"
refreshListener="#{DataOrganization.refreshOrphanVideos}"
/>
</h:form>
</ui:composition>
</html>
@Named(value="DataOrganization") // CDI
@SessionScoped // CDI
public class DataOrganizationBean implements Serializable, MonitoredBean {
private static final long serialVersionUID = 1686055743669628317L;
// Constants and variables
@EJB
private DataOrganizationEJB controller;
private Integer companyEntityID = null;
private VideoStatusTableModel videoTableModel;
private VideoStatus selectedVideo;
public void refreshOrphanVideos() {
setOrphanVideos(controller.getOrphanVideos(getCompanyEntityID()));
}
public void onOrphanVideoSelection(org.primefaces.event.SelectEvent event) {
this.setSelectedVideo(((VideoStatus) event.getObject()));
}
public VideoStatusTableModel getVideoTableModel() {
return videoTableModel;
}
public VideoStatus getSelectedVideo() {
return selectedVideo;
}
public void setSelectedVideo(VideoStatus selectedVideo) {
this.selectedVideo = selectedVideo;
}
}
¿alguien tiene una pista sobre cómo evitar volver a cargar la página web para obtener los oyentes del componente para trabajar?
En web XML he configurado el STATE_SAVING_METHOD
al cliente.
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
N.B .: utilizo JSF 2.0, Glassfish 3.1.2.2, PrimeFaces 3.4.
Gracias!
** * * ACTUALIZADO * ** *
descubrí realmente el problema proviene de los componentes. Si uso exactamente el mismo código sin el uso de componentes todo funciona bien.
¿Alguien ha encontrado este problema?
Descubrí que el problema realmente proviene de los componentes.Si uso exactamente el mismo código sin el uso de componentes todo funciona bien. ¿Alguien ha encontrado este problema? – fostiguy