JSF - 如何使用托管 bean 添加子项到 h:head 或 h:body
JSF - how to add child to h:head or to h:body with managed bean
我正在尝试测试我的托管 bean 以动态修改网页 (programmatically);大多数 jsf 示例展示了如何使用绑定来修改 ui 但是网页的其余部分呢?示例显示了如何到达通常位于 h:body
块中的 UIViewRoot
,但是 h:body
本身或 h:head
?
呢?
所以我的问题是...有没有办法使用 FacesContext
获取 h:body
或 h:head
作为父组件并使用托管 bean 向它们添加子组件或者请告知如何使用其他方式获得相似效果?
谢谢
您可以 display/hide 使用 rendered
属性的 JSF 组件。
下面是一个示例 -
<h:outputText value="Result = #{calculator.result}" rendered="#{calculator.result != null}"/>
此处,仅当 calculator.result
不是 null
时,此元素才会显示在 UI 中,其中 calculator
是您的 managedBean
和 result
是该 bean 中的一个变量。您可以在预渲染事件或 AJAX 调用或其他事件中更改此变量的值。
对于多个元素,您可以使用 <h:panelGroup>
和 rendered
属性。
UIViewRoot
由 <f:view>
标签表示。如果您没有在 JSF 页面中显式定义它,则会隐式添加它。
UIViewRoot which is usually located in h:body block
不,不是在body里面,而是默认围绕着body和头部。像这样:
<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">
<f:view> <!-- No need to define. Added implicitly here in ComponentTree -->
<h:head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
</h:head>
<h:body>
<h:outputText value="#{hello.message}"/>
</h:body>
</f:view>
</html>
因此,如果您使用 FacesContext.getCurrentInstance().getViewRoot()
获取 UIViewRoot 并请求其 children (.getChildren()
),您将获得包含 4 个元素的列表:
UIInstructions
:呈现 <html>
开始标记
UIOutput
:这是<h:head>
。再次请求 getChildren
以获得 <meta>
标签 的 UIOutput
HtmlBody
:这显然是h:body
。要求 getChildren
得到 <h:outputText>
UIInstructions
:呈现 </html>
结束标记
add children to them right with managed bean
是的,通常您可以使用 ManagedBean 来操作 UIComponentTree(例如,添加项目,然后重新加载页面以显示它)。但是,请考虑 JSF lifecycle 和处理顺序(例如,您不能在 render-phase 期间将 child 作为第一个元素添加到 body,因为项目已被处理)。
将新元素添加到 body:
的示例
List<UIComponent> viewRootChildren = FacesContext.getCurrentInstance().getViewRoot().getChildren();
for(UIComponent child : viewRootChildren){
if( child instanceof HtmlBody ){
HtmlOutputText newText = new HtmlOutputText();
newText.setValue("added dynamically");
child.add(newText);
}
}
我正在尝试测试我的托管 bean 以动态修改网页 (programmatically);大多数 jsf 示例展示了如何使用绑定来修改 ui 但是网页的其余部分呢?示例显示了如何到达通常位于 h:body
块中的 UIViewRoot
,但是 h:body
本身或 h:head
?
所以我的问题是...有没有办法使用 FacesContext
获取 h:body
或 h:head
作为父组件并使用托管 bean 向它们添加子组件或者请告知如何使用其他方式获得相似效果?
谢谢
您可以 display/hide 使用 rendered
属性的 JSF 组件。
下面是一个示例 -
<h:outputText value="Result = #{calculator.result}" rendered="#{calculator.result != null}"/>
此处,仅当 calculator.result
不是 null
时,此元素才会显示在 UI 中,其中 calculator
是您的 managedBean
和 result
是该 bean 中的一个变量。您可以在预渲染事件或 AJAX 调用或其他事件中更改此变量的值。
对于多个元素,您可以使用 <h:panelGroup>
和 rendered
属性。
UIViewRoot
由 <f:view>
标签表示。如果您没有在 JSF 页面中显式定义它,则会隐式添加它。
UIViewRoot which is usually located in h:body block
不,不是在body里面,而是默认围绕着body和头部。像这样:
<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">
<f:view> <!-- No need to define. Added implicitly here in ComponentTree -->
<h:head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
</h:head>
<h:body>
<h:outputText value="#{hello.message}"/>
</h:body>
</f:view>
</html>
因此,如果您使用 FacesContext.getCurrentInstance().getViewRoot()
获取 UIViewRoot 并请求其 children (.getChildren()
),您将获得包含 4 个元素的列表:
UIInstructions
:呈现<html>
开始标记UIOutput
:这是<h:head>
。再次请求getChildren
以获得<meta>
标签 的 HtmlBody
:这显然是h:body
。要求getChildren
得到<h:outputText>
UIInstructions
:呈现</html>
结束标记
UIOutput
add children to them right with managed bean
是的,通常您可以使用 ManagedBean 来操作 UIComponentTree(例如,添加项目,然后重新加载页面以显示它)。但是,请考虑 JSF lifecycle 和处理顺序(例如,您不能在 render-phase 期间将 child 作为第一个元素添加到 body,因为项目已被处理)。 将新元素添加到 body:
的示例List<UIComponent> viewRootChildren = FacesContext.getCurrentInstance().getViewRoot().getChildren();
for(UIComponent child : viewRootChildren){
if( child instanceof HtmlBody ){
HtmlOutputText newText = new HtmlOutputText();
newText.setValue("added dynamically");
child.add(newText);
}
}