我试图使用dataModel而不是绑定dataTable,但遇到了这个问题。在最后一列有一个commandButton,它应该用于从数据库中删除项。但是当我按下它时,java方法并没有启动。
xhtml的一部分(精简代码):
<h:form>
<rich:extendedDataTable
id="table"
var="fItem"
value="#{myFood.model}"
selectionMode="none">
<rich:column width="150px">
<f:facet name="header">Datum:</f:facet>
<h:outputText value="#{fItem.date}"/>
</rich:column>
<rich:column>
<h:commandButton id="save" action="#{myFood.delete}" value="delete"/>
</rich:column>
<f:facet name="footer">
<h:commandButton id="btnTest" action="#{myFood.test}" value="test"/>
</f:facet>
</rich:extendedDataTable>
</h:form>
MyFood.java:的一部分
public void delete()
{
System.out.println("TEST");
try
{
DaoCrud.delete(model.getRowData(), 'P');
}
catch (Exception e) {.....}
}
public void test()
{
System.out.println("TEST");
}
但即使是"TEST"也不会写入控制台!问题出在哪里?
更新:我已经更新了代码示例(facet&test()),它很有效。在我尝试使用dataModel private DataModel<Item> model;
之前,一切都很好。。。当我简单地将相同的commandButton移动到facet时,它就起作用了。
如果bean是请求范围的,那么您需要确保在bean(post)构造表单提交请求的过程中创建了与显示初始表单完全相同的模型。
private List<Item> list;
private DataModel<Item> model;
@PostConstruct
public void init() {
list = itemService.list();
model = new ListDataModel<Item>(list);
}
JSF将在应用请求值阶段对模型进行迭代,以确定按下的按钮,从而可以在调用应用程序阶段调用该按钮。
如果由于一些业务限制(例如缺少参数等),在后续请求中保留模型并不是一件小事,那么您需要将bean标记为@ViewScoped
而不是@RequestScoped
,从而将其放在视图范围中。只有当您使用JSF 2.0时,这才有效。
@ManagedBean
@ViewScoped
public class MyBean {}
或者,由于您使用的是RichFaces,因此也可以使用<a4j:keepAlive>
。把这个放在与表单相同的页面上:
<a4j:keepAlive beanName="#{myBean}" />
这与@ViewScoped
在JSF 2.0中所做的工作是一样的。
它应该在<h:form>
下
您的delete()
方法应该返回一个Object。如果签名不正确,就不会调用它。"签名必须与java.lang.Object action()匹配"。请参见此处。
据我所知,如果你想留在页面上,你可以直接返回null
。
public String delete()
{
System.out.println("TEST");
try
{
DaoCrud.delete(model.getRowData(), 'P');
}
catch (Exception e) {.....}
return null;
}
如果不想使用方法result进行导航,则可能需要将actionListener
属性及其相应的方法一起使用。如果您想在执行actionListener
之后重新渲染某些内容,也可以考虑使用<a4j:commandButton>
。