JSF2:动作和动作监听器
从 BalusC 的回答中 action 和 actionListener 之间的差异,使用 actionListener if您希望在执行实际业务操作之前有一个钩子,例如记录它,和/或设置附加属性(通过
)。然而,当我决定编写一些代码来测试这一点时,结果有点不同,这是我的小代码,这
<h:form id="form">
<h:panelGroup id="mygroup">
<p:dataTable id="mytable" value="#{viewBean.foodList}" var="item">
<p:column>
#{item}
</p:column>
<p:column>
<p:commandButton value="delete"
action="#{viewBean.delete}"
update=":form:mygroup">
<f:setPropertyActionListener target="#{viewBean.selectedFood}"
value="#{item}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:panelGroup>
</h:form>
是我的 bean
@ManagedBean
@ViewScoped
public class ViewBean {
private List<String> foodList;
private String selectedFood;
@PostConstruct
public void init(){
foodList = new ArrayList<String>();
foodList.add("Pizza");
foodList.add("Pasta");
foodList.add("Hamburger");
}
public void delete(){
foodList.remove(selectedFood);
}
//setter, getter...
}
根据 BalusC,actionListener
更合适。在这里,但我的示例显示否则。
上面的代码与 action
配合使用效果很好,但如果我切换到 actionListener
,则效果不太好。只需点击两次即可。我使用 actionListener
删除该表的条目,而如果我使用 action
,则每次单击按钮时都会删除条目,我想知道是否有 JSF 专家可以。帮助我理解 action
与 actionListener
注意 如果我切换到 actionListener
,我的 delete
方法成为public void delete(ActionEvent动作事件)
From this answer by BalusC here Differences between action and actionListener, Use actionListener if you want have a hook before the real business action get executed, e.g. to log it, and/or to set an additional property (by <f:setPropertyActionListener>,
. However when I decide to write some code to test this, the result is a bit different. Here is my small code
<h:form id="form">
<h:panelGroup id="mygroup">
<p:dataTable id="mytable" value="#{viewBean.foodList}" var="item">
<p:column>
#{item}
</p:column>
<p:column>
<p:commandButton value="delete"
action="#{viewBean.delete}"
update=":form:mygroup">
<f:setPropertyActionListener target="#{viewBean.selectedFood}"
value="#{item}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:panelGroup>
</h:form>
Here is my bean
@ManagedBean
@ViewScoped
public class ViewBean {
private List<String> foodList;
private String selectedFood;
@PostConstruct
public void init(){
foodList = new ArrayList<String>();
foodList.add("Pizza");
foodList.add("Pasta");
foodList.add("Hamburger");
}
public void delete(){
foodList.remove(selectedFood);
}
//setter, getter...
}
According to BalusC, actionListener
is more suitable here, but my example show otherwise.
The above code work great with action
, but if I switch over to actionListener
, then it does not quite work. It will take two clicks for me to delete an entry of this table using actionListener
, while if I use action
, it delete entry every time I click the button. I wonder if any JSF expert out there can help me understand action
vs actionListener
Note If I switch to actionListener
, my delete
method become public void delete(ActionEvent actionEvent)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您将
action
与actionListener
混淆了。actionListener
始终在action
之前运行。如果有多个操作侦听器,那么它们将按照注册的顺序运行。这就是为什么当您使用actionListener
调用业务操作并使用
设置(准备)要执行的属性时,它无法按预期工作。由业务操作使用。这个问题已在您之前的问题中指出并修复了 这是 Primefaces 错误还是Mojarra/MyFaces 错误。delete()
方法中的任何内容显然都是业务操作,应该由action
调用。业务操作通常会调用 EJB 服务,并且如有必要,还会设置最终结果和/或导航到不同的视图。You're confusing
action
withactionListener
. TheactionListener
runs always before theaction
. If there are multiple action listeners, then they run in the same order as they have been registered. That's why it doesn't work as expected when you useactionListener
to call the business action and<f:setPropertyActionListener>
to set (prepare) a property which is to be used by the business action. This problem was pointed out and fixed in your previous question Is this Primefaces bug or Mojarra/MyFaces bug.Whatever you have in the
delete()
method is clearly a business action and should be invoked byaction
instead. A business action typically invokes an EJB service and if necessary also sets the final result and/or navigates to a different view.我使用原始 JSF 标签
尝试了您的示例,但我也遇到了相同的症状。我相信如果您指定actionListener
属性,同时使用
声明另一个侦听器,即属性actionListener
中的侦听器> 将在其他人之前被解雇。更新:我用以下代码测试我的假设:
将您的
delete
函数更改为此:添加
内
。您将看到输出文本始终为
Chicken
。I tried your example with original JSF's tags
<h:commandButton>
but I also get the same symptom. I believe if you specifyactionListener
attribute and at the same time, declare another listener with<f:setPropertyActionListener>
, the listener in the attributeactionListener
will be fired before the other.UPDATE: I test my assumption with the following code:
Change your
delete
function to this one:Add
<h:outputText id="food" value="#{viewBean.selectedFood}" />
inside<h:panelGroup id="mygroup">
.You will see that the outputText is always
Chicken
.