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:bodyh:head 作为父组件并使用托管 bean 向它们添加子组件或者请告知如何使用其他方式获得相似效果?

谢谢

您可以 display/hide 使用 rendered 属性的 JSF 组件。

下面是一个示例 -

<h:outputText value="Result = #{calculator.result}" rendered="#{calculator.result != null}"/>

此处,仅当 calculator.result 不是 null 时,此元素才会显示在 UI 中,其中 calculator 是您的 managedBeanresult 是该 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 个元素的列表:

  1. UIInstructions:呈现 <html> 开始标记
  2. UIOutput:这是<h:head>。再次请求 getChildren 以获得 <meta> 标签
  3. UIOutput
  4. HtmlBody:这显然是h:body。要求 getChildren 得到 <h:outputText>
  5. 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);
    }
}