【问题标题】:Is there any technical advantage of actionListner attribute over action attribute in h:commandButton?与 h:commandButton 中的 action 属性相比,actionListner 属性是否有任何技术优势?
【发布时间】:2015-03-15 11:04:12
【问题描述】:

在核心 JSF 书(第 312 页)中,作者谈到了这一点:

请注意,单独的操作无法实现该行为 - 操作可以 导航到相应的页面,但无法确定 适当的页面,因为它对中的图像按钮一无所知 用户界面或鼠标点击。

下面是该示例中使用的 index.xhtml 和 ManagedBean:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
   <h:head>
      <h:outputStylesheet library="css" name="styles.css"/>
      <title>#{msgs.indexWindowTitle}</title>
   </h:head>

   <h:body>
      <span class="instructions">#{msgs.instructions}</span>
      <h:form>
         <h:commandButton image="/resources/images/mountrushmore.jpg" 
                          styleClass="imageButton"
                          actionListener="#{rushmore.handleMouseClick}"
                          action="#{rushmore.navigate}"/>
      </h:form>
   </h:body>
</html>

托管 Bean:

package com.corejsf;

import java.awt.Point;
import java.awt.Rectangle;
import java.util.Map;

import javax.faces.bean.ManagedBean; 
   // or import javax.inject.Named;
import javax.enterprise.context.RequestScoped; 
   // or import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

@ManagedBean // or @Named
@RequestScoped
public class Rushmore {
   private String outcome = null;
   private Rectangle washingtonRect = new Rectangle(70, 30, 40, 40);
   private Rectangle jeffersonRect = new Rectangle(115, 45, 40, 40);
   private Rectangle rooseveltRect = new Rectangle(135, 65, 40, 40);
   private Rectangle lincolnRect = new Rectangle(175, 62, 40, 40);

   public void handleMouseClick(ActionEvent e) {
      FacesContext context = FacesContext.getCurrentInstance();
      String clientId = e.getComponent().getClientId(context);
      Map<String, String> requestParams 
         = context.getExternalContext().getRequestParameterMap();

      int x = new Integer((String) requestParams.get(clientId + ".x")).intValue();
      int y = new Integer((String) requestParams.get(clientId + ".y")).intValue();

      outcome = null;

      if (washingtonRect.contains(new Point(x, y)))
         outcome = "washington";

      if (jeffersonRect.contains(new Point(x, y)))
         outcome = "jefferson";

      if (rooseveltRect.contains(new Point(x, y)))
         outcome = "roosevelt";

      if (lincolnRect.contains(new Point(x, y)))
         outcome = "lincoln";
   }

   public String navigate() {
      return outcome;
   }
}

我不明白作者为什么这么说,因为我试图只使用 action 属性并绑定到 commandButton,所以我修改了 index.xhtml 和托管 bean:

新的 index.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets">
   <h:head>
      <h:outputStylesheet library="css" name="styles.css"/>
      <title>#{msgs.indexWindowTitle}</title>
   </h:head>

   <h:body>
      <span class="instructions">#{msgs.instructions}</span>
      <h:form>
         <h:commandButton image="/resources/images/mountrushmore.jpg" id="commandButton" binding="#{rushmore.command}"
                          styleClass="imageButton" ac
                          action="#{rushmore.navigate}"/>
      </h:form>
      <ui:debug></ui:debug>
   </h:body>
</html>

新的托管 Bean:

package com.corejsf;

import java.awt.Point;
import java.awt.Rectangle;
import java.util.Map;

import javax.faces.bean.ManagedBean;
// or import javax.inject.Named;
import javax.faces.bean.RequestScoped;
// or import javax.faces.bean.RequestScoped;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

@ManagedBean
// or @Named
@RequestScoped
public class Rushmore {
    private String outcome = null;
    private Rectangle washingtonRect = new Rectangle(70, 30, 40, 40);
    private Rectangle jeffersonRect = new Rectangle(115, 45, 40, 40);
    private Rectangle rooseveltRect = new Rectangle(135, 65, 40, 40);
    private Rectangle lincolnRect = new Rectangle(175, 62, 40, 40);
    private UICommand command;

    public String navigate() {
        FacesContext context = FacesContext.getCurrentInstance();
        String clientId = command.getClientId(context);
        Map<String, String> requestParams = context.getExternalContext()
                .getRequestParameterMap();

        int x = new Integer((String) requestParams.get(clientId + ".x"))
                .intValue();
        int y = new Integer((String) requestParams.get(clientId + ".y"))
                .intValue();

        outcome = null;

        if (washingtonRect.contains(new Point(x, y)))
            outcome = "washington";

        if (jeffersonRect.contains(new Point(x, y)))
            outcome = "jefferson";

        if (rooseveltRect.contains(new Point(x, y)))
            outcome = "roosevelt";

        if (lincolnRect.contains(new Point(x, y)))
            outcome = "lincoln";

        return outcome;
    }

    public UICommand getCommand() {
        return command;
    }

    public void setCommand(UICommand command) {
        this.command = command;
    }
}

所以应用程序完全按照它应有的方式工作。 我的问题是在该示例中使用 actionListner 而不是仅使用 action 属性有什么技术优势(我知道从概念的角度来看,我们必须将业务逻辑与用户界面逻辑分开)?

【问题讨论】:

  • 这是可以接受的欺骗吗? stackoverflow.com/questions/3909267/… 如果没有,请更新您的问题以详细说明该答案是如何不足的。
  • @BalusC 我在发布问题之前阅读了该答案,但我看到您谈到了使用 actionListner 的原因:“和/或有权访问调用该操作的组件(即ActionEvent 参数可用)”。所以我只是想了解在上面的示例中使用 actionListner 是否有任何技术原因
  • 不。这纯粹是为了演示目的。只有在action 而不是actionListener 中确定outcome 部分才是有益的。现在,handleMouseClick() 动作监听器不能在期望不同结果的不同动作上重用。

标签: jsf jsf-2 action actionlistener commandbutton


【解决方案1】:

这个问题在 cmets 中得到了回答,所以我将复制 BalusC 的回复:

不。这纯粹是为了演示目的。只会是 如果结果部分是在行动中而不是在行动中确定的 动作监听器。现在 handleMouseClick() 动作监听器不是 可重复用于期望不同结果的不同操作

【讨论】:

    猜你喜欢
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多