我正在尝试测试我的托管bean动态修改网页(programmatically);大多数jsf示例显示如何使用绑定来修改ui但是网页的其余部分呢?这些示例显示了如何访问通常位于UIViewRoot
区块中的h:body
,但h:body
本身或h:head
呢?
所以我的问题是......是否有办法使用FacesContext
将h:body
或h:head
作为父组件并使用托管bean添加子项或者请告知如何使用其他方式获得相似效果?
由于
答案 0 :(得分:1)
UIViewRoot
由<f:view>
标记表示。如果您没有在JSF页面中明确定义它,则会隐式添加它。
UIViewRoot,通常位于h:body block
不,身体内部不,但默认情况下围绕身体和头部。像这样:
<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并询问其子项(.getChildren()
),您将获得4个元素的列表:
UIInstructions
:呈现<html>
开启标记UIOutput
:这是<h:head>
。再次要求getChildren
获取UIOutput
代码<meta>
HtmlBody
:显然这是h:body
。要求getChildren
获取<h:outputText>
UIInstructions
:呈现</html>
结束标记使用托管bean
添加子项
是的,一般情况下,您可以使用ManagedBeans来操作UIComponentTree(例如,添加项目,然后重新加载页面以显示它)。但是,请考虑JSF lifecycle和处理顺序(例如,您无法在渲染阶段将子项添加为正文的第一个元素,因为项目已经处理过)。 将新元素添加到正文的示例:
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);
}
}
答案 1 :(得分:0)
您可以使用rendered
属性显示/隐藏JSF组件。
以下是一个示例 -
<h:outputText value="Result = #{calculator.result}" rendered="#{calculator.result != null}"/>
此处,只有当calculator.result
不是null
且calculator
是managedBean
的名称且result
是<h:panelGroup>
时,此元素才会显示在用户界面中那个bean里面的变量。您可以在预渲染事件或AJAX调用或其他事件中更改此变量的值。
对于多个元素,您可以将rendered
与@register.filter(name='dj_iter')
def dj_iter(gen):
try:
return next(gen)
Except StopIteration:
return 'Completed Iteration'
属性一起使用。