0

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

观点,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 方法似乎停止执行第二次单击,并且在整个执行过程中我没有遇到任何异常。

4

1 回答 1

1

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

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

一般来说,最好让facelets通过c:if、ui:include src="#{...}"、c:choose等来处理组件树的修改(但跳过c:forEach)。

于 2013-04-26T19:07:16.903 回答