2011-06-06 102 views
2

我有一个表格,其中一列包含一个下拉列表(HtmlSelectItems组件)。 对于此表中的任何给定行,我希望能够根据特定的应用程序条件在运行时显示或隐藏下拉列表。JSF2.0-h:dataTable,列中包含下拉列表 - 显示/隐藏每个表格下拉列表的问题

我在这种情况下的解决方案是使用JSF2.0实现提供的组件的预呈现事件侦听器机制。基本上,在JSF页面中,我为HtmlSelectItems组件(位于h:列内)分配了一个id,并使用预渲染f:event元素对其进行了设置。 f:event指向我的一个接收组件ID并处理它的方法。

我的问题是HtmlSelectItems实例在所有表行之间共享,如果说我在一个下拉列表组件上调用HtmlSelectItems.setRender(false),所有后续行将停止显示下拉列表。事实上,在下拉菜单中调用第一个setRender(false)后,f:event预渲染侦听器将停止调用

我可以理解在表行 之间共享一个HtmlSelectItems实例对性能有积极影响总体而言,但是不应该在每一行上重新初始化这个组件实例吗?

非常感谢在这方面的任何澄清。

回答

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作为DataTable的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> 
+0

非常感谢BalusC的回答。我们将代码更改为使用“呈现”属性。我只是希望能够反思行的组件并修改它的状态,而不必指定“呈现”。 – user786611 2011-06-07 17:06:53

+0

不客气。既然你是新来者,如果答案有助于解决问题,请不要忘记标记为已接受。另见http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235 – BalusC 2011-06-07 17:11:18

+0

完成。再次感谢。 – user786611 2011-06-08 20:05:54