我有一个表,其中一个列包含一个下拉列表(HtmlSelectItems组件)。 对于此表中的任何给定行,我希望能够根据特定的应用程序条件在运行时显示或隐藏下拉列表。
我在这种情况下的解决方案是使用JSF2.0实现提供的组件的预渲染事件监听器机制。基本上在JSF页面中,我为HtmlSelectItems组件(生活在h:列中)分配了一个id,并使用pre render f:event元素设置它。 f:event指向我的一个接收组件id并处理它的方法。
我的问题是HtmlSelectItems实例在所有表行之间是SHARED,如果我在一个下拉列表组件上调用HtmlSelectItems.setRender(false),则所有后续行将停止显示下拉列表。实际上,一旦在下拉列表中调用第一个setRender(false),f:事件预呈现侦听器将停止被调用
我可以理解在表行之间共享一个HtmlSelectItems实例的事实 对整体性能有积极影响,但不应该在每一行重新初始化此组件实例吗?
非常感谢你对这方面的任何澄清。
答案 0 :(得分:1)
您需要让rendered
条件依赖于行本身,而不是父bean。
E.g。
<h:dataTable value="#{bean.list}" var="item">
<h:column>
<h:selectOneMenu rendered="#{item.showDropdown}">
...
</h:selectOneMenu>
</h:column>
</h:dataTable>
而不是
<h:dataTable value="#{bean.list}" var="item">
<h:column>
<h:selectOneMenu rendered="#{bean.showDropdown}">
...
</h:selectOneMenu>
</h:column>
</h:dataTable>
或者,如果由于某些设计限制需要由#{bean}
而不是#{item}
确定,那么有几种方法。
如果您使用DataModel
作为数据表的value
,那么您可以按如下方式获取当前行:
public boolean isShowDropdown() {
Item item = model.getRowData();
return shouldShowDropdown(item); // Do your thing.
}
如果没有,则保持Map<Long, Boolean>
,而密钥实际上是行项的标识符,值表示是否应显示下拉列表。然后可以按如下方式使用:
<h:dataTable value="#{bean.list}" var="item">
<h:column>
<h:selectOneMenu rendered="#{bean.showDropdown[item.id]}">
...
</h:selectOneMenu>
</h:column>
</h:dataTable>