我有下面的 Test.xhtml,我可以在其中选择“海/空”模式。我不想将所有 4 个页面(Page1.xhtml、Page2.xhtml、Page3.xhtml、Page4.xhtml)加载到 jsf 视图树中。在我的场景中,模式一旦选择并保存就无法更改为其他模式。保存的模式将显示为查看模式。因为在任何时候我只需要 2 个文件(Page1.xhtml、Page2.xhtml(或)Page3.xhtml、Page4.xhtml)...我正在使用 JSTL 标记处理程序来动态包含页面。下面的事情工作正常。但我无法理解渲染是如何工作的。
测试.xhtml
<!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:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head><title>JSF And JSTL</title>
<link href="../css/styles.css"
rel="stylesheet" type="text/css"/>
</h:head>
<h:body>
<div align="center">
<h:form id="form1">
<h:panelGrid columns="2">
<h:outputLabel value="Select Mode"/>
<h:selectOneMenu id="selectPageId" value="#{testBean.selectedMode}">
<f:selectItem itemLabel="Select" />
<f:selectItem itemLabel="Sea" itemValue="sea" />
<f:selectItem itemLabel="Air" itemValue="air" />
<f:ajax execute="@this" render="pageGroup"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGroup id="pageGroup">
<c:if test="#{'sea' eq testBean.selectedMode}">
<ui:include src="Page1.xhtml" />
<ui:include src="Page2.xhtml" />
</c:if>
<c:if test="#{'air' eq testBean.selectedMode}">
<ui:include src="Page3.xhtml" />
<ui:include src="Page4.xhtml" />
</c:if>
</h:panelGroup>
</h:form>
</div>
</h:body>
</html>
测试Bean.java
package com.test;
@ManagedBean(name = "testBean")
@ViewScoped
public class TestBean {
private String selectedMode;
public String getSelectedMode() {
return selectedMode;
}
public void setSelectedMode(String selectedMode) {
this.selectedMode = selectedMode;
}
}
再次更新
请帮忙澄清以下内容。
当我第一次发送请求访问时Test.xhtml
,jsf 视图(UIViewRoot
) 被创建。自从testBean.selectedMode
默认为 null..此创建的视图将不包含任何组件详细信息<c:if>
and <ui:include>
哪些在里面<h:panelGroup id="pageGroup">
.
之后,当我通过选择模式发送第二个请求(ajax 回发)时sea, the UIViewRoot
再次为请求创建恢复视图阶段. While UIViewRoot
在恢复视图阶段为此请求创建标签处理程序(<c:xxx>, <f:xxx>, <ui:include>
)将被执行。
由于所选值“sea”将更新为 model(TestBean.java
) 只有在更新模型值阶段,在恢复视图阶段 EL#{testBean.selectedMode}
将被评估为 null。
因此,在我的示例 Test.xhtml 页面中,两个标记处理程序(<c:if test="#{'sea' eq testBean.selectedMode}">
and <c:if test="#{'air' eq testBean.selectedMode}">
) 将被评估为 false。所以UIViewRoot
不包含任何与内部组件相关的信息<h:panelGroup id="pageGroup">
.
尽管UIViewRoot
不包含里面的组件信息<h:panelGroup id="pageGroup">
, JSF 如何呈现包含的页面(<ui:include src="Page1.xhtml" />,<ui:include src="Page2.xhtml" />
) 成功地?
我不确定 JSF 渲染是如何发生的。渲染时,JSF 是否为特定渲染部分重新创建组件树(<h:panelGroup id="pageGroup">
).?
Note:当我选择模式为海/空时,该示例工作正常。相应的部分渲染正确。