包含Facelet与FaceletContext #includeFacelet()在JSF 2.0中不起作用

时间:2013-04-26 14:50:38

标签: jsf-2 facelets

我正在尝试使用FaceletContext#includeFacelet()以编程方式将Facelet注入主页的一部分(我不能使用<ui:include>)并在阅读this question的答案后,编写了以下代码(这是一个简单的测试用例):

视图,index.xhtml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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:p="http://primefaces.org/ui"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:c="http://java.sun.com/jsp/jstl/core">
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
        <title>Insert title here</title>
        <script src="JS/jquery-1.8.3.js" />
        <script type="text/javascript">
            $(function(){
                $('#mondiv').click(function(){
                    console.log("mondiv is clicked !");                     
                    includefacelet();
                });
            });
        </script>
    </h:head>
    <body>
        <h:form id="form1">
            <div id="mondiv" style="background-color: red; position: absolute; width: 20px; height: 20px;" />
            <p:remoteCommand name="includefacelet" actionListener="#{bean.includefacelet}" />
            <br /><br />
            <h:panelGroup id="pg" layout="block" style="background-   color:blue;position:absolute;width:200px;height:200px;" />
        </h:form>
    </body>
</html>

托管bean:

package beans.a4jTests;

import java.io.IOException;

import javax.faces.application.Application;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.component.html.HtmlPanelGroup;
import javax.faces.context.FacesContext;
import javax.faces.view.facelets.FaceletContext;

import org.primefaces.context.RequestContext;

@ManagedBean
@SessionScoped
public class Bean {

    public void includefacelet(){
        FacesContext fc = FacesContext.getCurrentInstance();
        UIForm form1 = (UIForm) fc.getViewRoot().findComponent("form1");
        HtmlPanelGroup pg = (HtmlPanelGroup) form1.findComponent("pg");
        FaceletContext faceletContext = (FaceletContext) fc.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);

        try {
            faceletContext.includeFacelet(pg, "NewFile.html");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //Refrsh
        RequestContext context = RequestContext.getCurrentInstance();         
        context.update("form1");
        context.update("pg");
        System.out.println("includefacelet is executed");
    }

}

包含,newfile.html

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
        <title>Insert title here</title>
    </head>
    <body>
        Hello ! this is the newfile.html
    </body>
</html>

我不知道为什么,即使bean方法被执行也不会发生任何事情,但是bean方法似乎停止执行第二次单击并且在整个执行期间我没有得到任何异常。

1 个答案:

答案 0 :(得分:1)

调用FaceletContext.includeFacelet()将不起作用,因为Facelet引擎在内部使用该方法。用户不应该这样做。我的建议是不要在托管bean中使用FaceletContext。

相反,在我看来,最好的方法是使用<ui:include src=#{someELPointingToTheTargetFacelet}/>。通过这种方式,facelets可以事先知道内容是“动态的”并采取适当的预防措施。

通常,最好让facelets通过c来处理组件树修改:if,ui:include src =“#{...}”,c:choose等等(但跳过c:forEach)。