【发布时间】: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