2012-09-25 10 views
5

Mam stronę internetową, która zawiera stronę podrzędną, która zmienia się zgodnie z elementem, który wybrałem w menu dokowania primfaces (ui:include). Niektóre podstrony zawierają niestandardowy komponent kompozytowy, który zaimplementowałem. Pierwsza strona, na której wyświetla się aplikacja internetowa, ma poprawnie działających wszystkich swoich słuchaczy. Po zmianie podstrony za pomocą menu dokowania, słuchacze VideoStatusTable (słuchacze komponentów kompozytowych) nie będą działali, dopóki nie odświeżę strony w przeglądarce (z F5) LUB jeśli ponownie wybiorę stronę w menu dokowania.Detektory komponentów kompozytowych działają tylko po przeładowaniu strony.

Oto strona główna z menu dokowania.

<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 wygląda następująco:

@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 (który służy do wybierania, który jest pokazany widok):

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; 
    } 
} 

Zwyczaj komponent:

<?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 }); 
    } 

} 

Pierwsza podstrona (oraz jego Bean), który zawiera komponent:

<?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); 
    } 
    } 

Kolejna podstrona, który zawiera ten sam składnik (tutaj słuchacze nie działają aż odświeżyć stronę (za pośrednictwem stacji dokującej lub jeśli uderzę 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; 
    } 
} 

czy ktoś ma pojęcia o tym, jak uniknąć przeładowania strony internetowej, aby słuchacze komponentu do pracy?

W web XML ustawiłem STATE_SAVING_METHOD na klienta.

<context-param> 
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
    <param-value>client</param-value> 
</context-param> 

N.B .: używam JSF 2.0, GlassFish 3.1.2.2, Primefaces 3.4.

Dzięki!

** * * AKTUALIZACJA * ** *

dowiedziałem się problem rzeczywiście pochodzi od składników. Jeśli użyję tego samego kodu bez użycia komponentów, wszystko działa dobrze.

Czy ktoś napotkał ten problem?

+0

Dowiedziałem się, że problem naprawdę pochodzi z komponentów.Jeśli użyję tego samego kodu bez użycia komponentów, wszystko działa dobrze. Czy ktoś napotkał ten problem? – fostiguy

Odpowiedz

1

miałem ten sam problem, ale na pewno należy unikać w ten sposób! Powinieneś robić mniej ogólnych składników. To zadziałało dla mnie.

Powiązane problemy