如何在 JSF 的表中动态添加一行?
Posted
技术标签:
【中文标题】如何在 JSF 的表中动态添加一行?【英文标题】:How to Dynamically add a row in a table in JSF? 【发布时间】:2011-01-17 17:06:48 【问题描述】:在我的应用程序中,我需要在单击按钮时添加一行,并且此按钮将位于所有行中。需要帮助吗?
物品类
public class Item
public Item()
private String value;
public Item(String value) this.value = value;
public void setValue(String value) this.value = value;
public String getValue() return value;
管理 Bean 类
public class MyMB
private List<Item> list;
public void addItem() // JSF action method
list.add(new Item("Default"));
Iterator<Item> iterator = list.iterator();
while(iterator.hasNext())
Item item = (Item)iterator.next();
System.out.println(item.getValue());
System.out.println();
/**
* @return the list
*/
public List<Item> getList()
if(list==null)
loadList();
return list;
private void loadList()
list = new ArrayList<Item>();
list.add(new Item("Data"));
JSF 代码
<h:form>
<rich:dataTable value="#myMB.list" var="item" id="tabel">
<h:column><h:inputText value="#item.value" /></h:column>
<h:column><a4j:commandButton value="Add" actionListener="#myMB.addItem" reRender="tabel"/></h:column>
【问题讨论】:
【参考方案1】:您需要做的基本上只是在h:dataTable
的value
属性后面的数据模型中添加一个空对象。
但同样的空行也需要在后续请求中保留。如果支持 bean 是请求范围的,那么数据模型会在没有空行的情况下重新加载。当 bean 是会话范围时,这一切都应该工作。
此外,您的 JSF 代码中还有几个错误。 h:dataTable
var
属性缺失,列内容需要在h:column
内。
<h:form>
<h:dataTable value="#bean.list" var="item">
<h:column><h:inputText value="#item.value" /></h:column>
</h:dataTable>
<h:commandButton value="Add" action="#bean.add"/>
</h:form>
会话或视图范围 bean 可能如下所示:
public class Bean
private List<Item> list;
public Bean()
list = new ArrayList<Item>();
public void add()
list.add(new Item());
public List<Item> getList()
return list;
Item
类当然应该有一个默认的无参数构造函数。通常这已经是隐式可用的,但是如果你用参数定义自己的构造函数,那么它就不再可用了。你需要明确定义它,否则你不能再做Item item = new Item();
了。
public class Item
private String value;
public Item()
// Keep default constructor alive.
public Item(String value)
this.value = value;
// ...
如果您希望将 bean 保持在 请求范围,那么您需要保持新添加的项目的数量,以便 bean 在加载时可以保持相同的数量。 p>
public class Bean
private List<Item> list;
private htmlInputHidden count = new HtmlInputHidden();
public Bean()
count.setValue(0);
public void add()
list.add(new Item());
public List<Item> getList()
if (list == null) loadList();
return list;
public HtmlInputHidden getCount()
return count;
public void setCount(HtmlInputHidden count)
this.count = count;
private void loadList()
list = new ArrayList<Item>();
// Preserve list with newly added items.
for (int i = 0; i < (Integer) count.getValue(); i++)
list.add(new Item());
您只需将以下内容添加到 JSF 页面的 <h:form>
:
<h:inputHidden binding="#bean.count" converter="javax.faces.Integer" />
有关以任何方式使用数据表的更多见解,您可能会发现这篇文章很有用:Using Datatables。它还包含一个 WAR 文件,其中包含请求和会话范围内的大量示例。
【讨论】:
@BalusC :我对这种技术有疑问,当我按下按钮时,整个页面都会正确刷新,我们可以使用 Ajax 来完成这一切,以便这个过程是异步的。 是的,你可以。由于您还没有使用 JSF 2.0,因此您需要插入一些 3rd 方组件库。我可以向您推荐 JBoss RichFaces 的 Ajax4jsf 子组件。了解更多:jboss.org/file-access/default/members/jbossajax4jsf/freezone/… 通过您提供的链接,我尝试更改代码以支持 ajax。我收到一个错误,即 '#myMB.addItem' Method not found:....但我有Bean 类中的那个方法。我已经编辑了我的代码...请帮助 使用action
代替actionListener
,或更改addItem
以采用ActionEvent
参数。【参考方案2】:
以这张表为例:
<h:datatable value="#myBean.list" ...>
...
<h:column>
<h:commandButton value="Add a row" action="#myBean.addRow"/>
</h:column>
</h:datatable>
myBean.addRow 方法只会在列表中添加一个新元素:
public class MyBean
private List<SomeClass> list;
...
public List<SomeClass> getList()
return list;
public void addRow()
list.add(new SomeClass());
当您点击按钮时,方法addRow 将在list 中添加一个新元素。页面将刷新并显示带有新行的表格。
编辑:
关于你的后期编辑,三件事:
第 1 点:能否附上你的错误的堆栈跟踪?
第 2 点: 您的方法 addRow 返回一个 String
,它是 JSF 用于导航的 ID。由于此操作不涉及任何导航(即用户停留在同一页面上),只需返回null
或""
:
public String addRow()
list.add(new Item("new data"));
return null;
第 3 点:我建议你的类 Item
提供一个空的构造函数(除了你当前的构造函数):
public Item()
【讨论】:
在 Bean 类的第 2 行中你提到了 SomeElement 并且在 getter 方法中你提到了 SomeClass...你能澄清一下 对不起,这只是一个错字。我已经编辑了我的帖子。当然,我使用的是同一种对象(因为您没有提供任何代码 sn-p,所以我对您的 JSF 页面和 bean 中的内容做了一些假设)。 您好,我已附上我的代码,但出现错误。您能帮忙。 @Hari 我已经编辑了我的帖子。如果我的建议不能解决您的问题,请提供您错误的堆栈跟踪... 感谢 romaintaz 我没有收到任何错误。但是添加的数据没有反映在屏幕上,当我迭代项目列表时,我可以在控制台中看到添加的数据。以上是关于如何在 JSF 的表中动态添加一行?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 JSF 中动态添加 <h:inputtext>? [复制]