2012-09-25 9 views
5

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?

+0

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

Respuesta

1

he tenido el mismo problema, pero que realmente debería evitar hacer esto! Debe hacer menos componentes genéricos. Funcionó para mí

Cuestiones relacionadas