JSF2:动作和动作监听器

发布于 2024-12-24 16:47:42 字数 1996 浏览 4 评论 0原文

从 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 专家可以。帮助我理解 actionactionListener

注意 如果我切换到 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我为君王 2024-12-31 16:47:42

您将 actionactionListener 混淆了。 actionListener 始终在 action 之前运行。如果有多个操作侦听器,那么它们将按照注册的顺序运行。这就是为什么当您使用 actionListener 调用业务操作并使用 设置(准备)要执行的属性时,它无法按预期工作。由业务操作使用。这个问题已在您之前的问题中指出并修复了 这是 Primefaces 错误还是Mojarra/MyFaces 错误

delete() 方法中的任何内容显然都是业务操作,应该由 action 调用。业务操作通常会调用 EJB 服务,并且如有必要,还会设置最终结果和/或导航到不同的视图。

You're confusing action with actionListener. The actionListener runs always before the action. 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 use actionListener 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 by action instead. A business action typically invokes an EJB service and if necessary also sets the final result and/or navigates to a different view.

执笔绘流年 2024-12-31 16:47:42

我使用原始 JSF 标签 尝试了您的示例,但我也遇到了相同的症状。我相信如果您指定 actionListener 属性,同时使用 声明另一个侦听器,即属性 actionListener 中的侦听器> 将在其他人之前被解雇。

更新:我用以下代码测试我的假设:

  • 将您的delete函数更改为此:

    公共无效删除(){
        this.selectedFood = "鸡";
        //foodList.remove(selectedFood);
    }
    
  • 添加

您将看到输出文本始终为Chicken

I tried your example with original JSF's tags <h:commandButton> but I also get the same symptom. I believe if you specify actionListener attribute and at the same time, declare another listener with <f:setPropertyActionListener>, the listener in the attribute actionListener will be fired before the other.

UPDATE: I test my assumption with the following code:

  • Change your delete function to this one:

    public void delete(){
        this.selectedFood = "Chicken";
        //foodList.remove(selectedFood);
    }
    
  • Add <h:outputText id="food" value="#{viewBean.selectedFood}" /> inside <h:panelGroup id="mygroup">.

You will see that the outputText is always Chicken.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文