在h:commandButton中,actionListener属性是否比action属性有任何技术优势?

时间:2015-01-16 18:51:17

标签: jsf jsf-2 action actionlistener commandbutton

在核心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>

Managed 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属性?

1 个答案:

答案 0 :(得分:0)

在评论中回答了这个问题,所以我将复制BalusC的回复:

  

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