FaceletContext.includeFacelet麻烦

时间:2012-02-21 14:21:04

标签: jsf dynamic enterprise

我目前正在尝试将预定义的jsf页面插入主jsf页面的特定部分。我已经能够使用以下方法成功实现这一目标:

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是我的托管bean(dynamicComponentBean)中的字段变量,它绑定到主jsf页面中的HtmlPanelGrid,而actualPath变量是指示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的页面的一个小例子如下:

<?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对象来完成所有页面生成。但是,如果没有创建单独的状态会话bean来以类似的方式生成所有这些不同的页面,我已经设置它以了解何时调用集成应用程序中的这些页面并使用includeFacelet方法将它们放入动态组件面板中。

1 个答案:

答案 0 :(得分:0)

尝试使用

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