有条件地渲染一个 <ui:include>
Posted
技术标签:
【中文标题】有条件地渲染一个 <ui:include>【英文标题】:Conditionally rendering an <ui:include> 【发布时间】:2013-09-13 06:21:38 【问题描述】:我正在尝试切换显示<rich:dataTable>
的页面。在我只包含<ui:include>
模板之前,它只会一直显示表格。
<ui:include src="../log/viewDlg.xhtml"/>
现在我希望能够在网页上打开/关闭它。在页面上显示可能带有按钮或链接。我怎样才能实现它?
更新 1:由于某种奇怪的原因,我无法让它显示出来,这是我目前根据反馈写的内容
查看:
<a4j:commandLink value="View"
action="#bean.showview" render="viewPanel"/>
<h:panelGroup id="viewPanel">
<h:panelGroup id="tableRenderPanel" rendered="#bean.showPolicyView">
<ui:include src="../log/viewDlg.xhtml"/>
</h:panelGroup>
</h:panelGroup>
支持 bean:
private boolean showPolicyView = false;
public void showView()
showPolicyView = !showPolicyView;
public boolean isShowPolicyView()
return showPolicyView;
【问题讨论】:
【参考方案1】:我更喜欢使用ui:include
,而不是像这里插入h:panelBoxes
:
<ui:fragment rendered="#myBean.yourCondition()">
<ui:include src="viewA.xhtml"/>
</ui:fragment>
<ui:fragment rendered="#not myBean.yourCondition()">
<ui:include src="viewB.xhtml"/>
</ui:fragment>
优点:标签处理程序不代表组件,并且一旦构建视图就永远不会成为组件树的一部分。它不会干扰您的 CSS - 相反,h:panelBox
会插入 div 或 span。
...另一种方法是 c:choose,它可以工作,但会导致渲染阶段问题。
<c:choose>
<c:when test="#myBean.yourCondition()">
<ui:include src="viewA.xhtml"/>
</c:when>
<c:otherwise>
<ui:include src="viewB.xhtml"/>
</c:otherwise>
</c:choose>
警告:在使用标签处理程序(如任何c:xxx
)时,请务必了解difference between UI Components and Tag Handlers。即 UI 组件和标签处理程序在不同阶段渲染。这意味着您不能在复合组件中创建变量并在嵌套标记处理程序中使用它。 c:choose
和 ui:include
都是标签处理程序,所以通常这不是问题。阅读链接,这是一个非常简短且非常有见地的示例。
【讨论】:
【参考方案2】:将<ui:include>
包裹在两个<h:panelGroup>
元素中。这里有个问题,你不能重新渲染一个条件组件。这是为什么?因为当元素的rendered
属性解析为false
时,在渲染视图时不会考虑它,因此它不能成为操作的目标(在这种情况下,与渲染有关)。
跳转到代码,你会得到这个:
<h:panelGroup id="wrapperPanel">
<h:panelGroup id="tableRenderPanel" rendered="#yourBean.renderTable">
<ui:include src="../log/viewDlg.xhtml"/>
</h:panelGroup>
</h:panelGroup>
yourBean#renderTable
是一个Boolean
属性,用于确定是否将呈现组件。当计算结果为false
时,该组件不包含在组件树中。
切换视图
要切换视图,只需创建一个刷新页面的 bean 方法
<h:commandLink action="#yourBean.toggleTableView"/>
或通过 AJAX 的特定面板。要在 JSF 1.2 中做到这一点,如果可以的话,请依靠 RichFaces 之类的扩展来引入 AJAX。例如,如果您选择 RichFaces,您可以使用 <a4j:commandLink/>
及其方便的 render
(或旧版本中的 reRender
)属性来实现在 JSF 2 中使用 <f:ajax/>
可以正常执行的操作
<a4j:commandLink action="#yourBean.toggleTableView" reRender="wrapperPannel"/>
或者,另一种选择是
<a4j:commandLink action="#yourBean.toggleTableView">
<a4j:support event="oncomplete" reRender="wrapperPannel"/>
</a4j:commandLink>
请注意,reRender
属性可能会根据您的页面结构而有所不同,但它应该始终引用最后包装面板的 id。此外,在 RichFaces 的后期版本中,reRender
被简单地重命名为 render
。
所以,假设您在yourBean
中有一个renderTable
属性(getter + setter),toggleTableView
必须更改它,以便动态定义是否要渲染组件(renderTable = false
) .
RichFaces 简介
查看this link 以获取在您的项目中设置 RichFaces 的帮助。
【讨论】:
@GilbertV 哦,我明白了,我很傻。f:ajax
稍后介绍。如果可以,请在与 JSF 1.2 兼容的版本中使用诸如 RichFaces 或 PrimeFaces 之类的 JSF 扩展。这些为以前的 JSF 版本添加了很好的 AJAX 提升。我将更新我的答案以使其 1.2 友好。
@GilbertV 这里有些奇怪,h:commandLink
没有render
属性。如果您再次检查答案,会有一个非常小的区别:它是 a4j:commandLink
而不是 h:commandLink
。 a4j
属于 RichFaces。
@GilbertV 单击链接时,您是否收到任何有关未找到 id 的错误?
@GilbertV 我添加了一个新选项,它使用来自早期版本 RichFaces 的旧 a4j:support
元素。如果你有,试试看。此外,wrapperPanel
可以从 h:panelGroup
更改为 a4j:outputPanel
。
@GilbertV 支持指令与特定事件相关联。在这种情况下,请尝试event="oncomplete"
。以上是关于有条件地渲染一个 <ui:include>的主要内容,如果未能解决你的问题,请参考以下文章
当有条件地渲染两个组件时,每个组件都包含一个 react-native-elements <Input>,激活一个会导致组件异常/不渲染