2012-02-21 111 views
2

我正在嘗試將預定義的jsf頁面插入主jsf頁面的特定部分。我已經能夠做到這一點半成功地利用了以下內容:FaceletContext.includeFacelet麻煩

public void includeFacelet(String pageString){ 
    //NOTE SEE BELOW 
    centerPanelGrid.getParent().getChildren().clear(); 

    centerPanelGrid.getChildren().clear(); 

    String actualPath = "faceletFolder/".concat(pageString).concat(".xhtml"); 

    try{ 
      FacesContext facesContext = FacesContext.getCurrentInstance(); 
      FaceletContext faceletContext = (FaceletContext)facesContext.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY); 
      faceletContext.includeFacelet(centerPanelGrid, actualPath); 
    }catch(IOException ex){ 
      ...   
    } 
} 

凡centerPanelGrid是在其中綁定到HtmlPanelGrid主JSF頁面和actualPath變量中我的託管bean(dynamicComponentBean)字段變量是指示jsf頁面位置的相對路徑。

至於說明,這似乎是無意義的必須有這條線(相信我,我意識到這一點)然而,在我所有的測試中,如果我沒有那條線,那麼當我去包括JSF頁面就不會包含任何...

這是主要的JSF頁面的摘要:

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:p="http://primefaces.org/ui"> 
    <h:head> 
     <title>User Page</title> 
    </h:head> 
    <h:body> 

     <p:layout fullPage="true"> 

      <p:layoutUnit position="north" size="45" header="header"/> 

      <p:layoutUnit position="south" size="100" resizable="true"> 
       [Footer Text] 
      </p:layoutUnit> 

      <p:layoutUnit position="west" size="200" resizable="true"> 
       [West Content] 
      </p:layoutUnit> 

      <p:layoutUnit position="east" size="200" resizable="true"> 
       [East Content] 
      </p:layoutUnit> 

      <p:layoutUnit position="center" resizable="true" id="dynamicLayout"> 
       <h:panelGrid id="dynamicContent" binding="#{dynamicComponentBean.centerPanelGrid}"/> 
      </p:layoutUnit> 

     </p:layout> 
    </h:body> 
</html> 

而那些有可能導致插入centerPanelGrid將作爲follws頁面的一個小例子:

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:p="http://primefaces.org/ui" 
     xmlns:f="http://java.sun.com/jsf/core"> 

    <h:head> 
     <title>Reports Interface</title> 
    </h:head> 

    <h:body> 
     <h:form> 
      <h:panelGrid columns="3" columnClasses="rightalign,leftalign,leftalign"> 

       <h:outputText value="Find Daily Report"/> 
       <p:calendar id="dailyCalendar" value="#{reports.dailyDate}" mode="popup" effect="slide"/> 
       <h:commandButton id="findDailyReport" value="Search" action="#{dynamicComponentBean.includeFacelet('navString')}"/> 

      </h:panelGrid> 

      <h:message for="dailyCalendar"/> 

     </h:form> 
    </h:body> 
</html> 

使用navString作爲我傳遞給它的任何字符串,以便includeFacelet方法可以將相應的jsf拉到下一個。

當我嘗試使用命令按鈕進行導航時,出現了問題,它需要我按兩次才能工作,第一次按按鈕使其看起來像刷新頁面或其他東西,然後隨後的點擊允許我包含centerPanelGrid中正確的facelet。

我在issuse上做了大量的調試,我發現在第一次點擊時,它沒有調用任何託管的bean中的任何方法,實際上並沒有進入我的任何代碼。我不知道爲什麼要這樣做,或者我需要做些什麼才能讓它包含我想要的facelet並讓它正常導航。

實質上,這些網頁來自另外一個企業應用程序,該應用程序是獨立開發並集成到當前系統中的。當前系統通過手動創建代表所有各種UIComponent並將它們放入適當位置的Java對象來完成所有頁面生成。然而,爲了創建獨立的statele會話bean,以類似的方式生成所有這些不同的頁面,我已經設置了它來了解何時調用集成應用程序中的這些頁面,並使用includeFacelet方法將它們放入動態組件面板中。

+0

問題很好嘗試。在完成我的工作後,我會檢查它 – 2012-02-21 14:22:47

+1

任何你不能使用'ui:include src =「#{dynamicComponent.currentPath}」''而不是通過編程方式處理facelets的原因嗎? – mrembisz 2012-02-21 14:33:30

+0

@mrembisz'ui:include'組件只能在另一個XHTML頁面上使用,另一個使用'ui:composition'標籤。從它的聲音中,OP正在處理他可能無法控制的第三方頁面。 – 2012-02-21 15:29:10

回答

0

使用

faceletContext.includeFacelet(centerPanelGrid.getParent(), actualPath);