如果 JSF 不支持,为什么我可以将 <f:actionListener> 绑定到任意方法?
Why am I able to bind <f:actionListener> to an arbitrary method if it's not supported by JSF?
我正在使用 Glassfish 3.1.2.2 和 JSF Mojarra 2.1.6。
我有以下 Facelets 页面:
<h:form>
<h:commandLink value="link">
<f:actionListener binding="#{backingBean.someMethod(1)}"/>
</h:commandLink>
</h:form>
以及以下辅助 bean:
@RequestScoped
@ManagedBean
public class BackingBean {
public void someMethod(int i) {
System.out.println("It was called: " + i);
}
}
当我单击 link 时,"Info: It was called: 1" 出现在控制台中。
binding
的文档如下:
Library: http://xmlns.jcp.org/jsf/core, http://java.sun.com/jsf/core (Jsf Core)
Tag: actionListener
binding
Value binding expression that evaluates to an object that implements javax.faces.event.ActionListener. [emphasis mine]
此外,this question 的公认答案指出 f:actionListener
不可能调用任意方法。
如果不支持,为什么要调用支持 bean 方法?
这是新的 EL 2.2 功能的结果,它通过 #{bean.method()}
语法调用值表达式中的方法,而不是仅通过 #{bean.property}
语法引用 属性(这确实应该是确切的类型 ActionListener
)。它不会在 EL 2.1 或更早的版本中工作,并且当您删除参数和括号时它也不会工作。该文档是在 EL 2.2 不存在时编写的(与 2006 年 5 月的 JSF 1.2 version 相比,它实际上没有修改;EL 2.2 于 2009 年 12 月推出)。然而,我同意它需要更新那部分,因为它会让初学者感到困惑。
您找到的答案基于文档提出了自己的观点,但是回答者似乎没有根据问题意识到虽然 binding="#{testController.nodeListener}"
失败了,但 binding="#{testController.nodeListener(event)}"
实际上 有效。这只是不给你通过 ActionEvent
的机会。如果它建议仅使用 binding="#{testController.nodeListener()}"
并以其他方式获取事件信息,例如通过调用 UIComponent#getCurrentComponent()
或什至将 #{component}
作为参数传递,则答案会更好。当然,只有当你真的需要用到它的时候。
<h:commandLink value="link">
<f:actionListener binding="#{bean.someMethod(component)}"/>
</h:commandLink>
public void someMethod(UIComponent component) {
System.out.println("It was called on: " + component); // HtmlCommandLink
}
另请参阅:
- Invoke direct methods or methods with arguments / variables / parameters in EL
- Difference between JSP EL, JSF EL and Unified EL
- Differences between action and actionListener
我正在使用 Glassfish 3.1.2.2 和 JSF Mojarra 2.1.6。
我有以下 Facelets 页面:
<h:form>
<h:commandLink value="link">
<f:actionListener binding="#{backingBean.someMethod(1)}"/>
</h:commandLink>
</h:form>
以及以下辅助 bean:
@RequestScoped
@ManagedBean
public class BackingBean {
public void someMethod(int i) {
System.out.println("It was called: " + i);
}
}
当我单击 link 时,"Info: It was called: 1" 出现在控制台中。
binding
的文档如下:
Library: http://xmlns.jcp.org/jsf/core, http://java.sun.com/jsf/core (Jsf Core)
Tag: actionListener
binding
Value binding expression that evaluates to an object that implements javax.faces.event.ActionListener. [emphasis mine]
此外,this question 的公认答案指出 f:actionListener
不可能调用任意方法。
如果不支持,为什么要调用支持 bean 方法?
这是新的 EL 2.2 功能的结果,它通过 #{bean.method()}
语法调用值表达式中的方法,而不是仅通过 #{bean.property}
语法引用 属性(这确实应该是确切的类型 ActionListener
)。它不会在 EL 2.1 或更早的版本中工作,并且当您删除参数和括号时它也不会工作。该文档是在 EL 2.2 不存在时编写的(与 2006 年 5 月的 JSF 1.2 version 相比,它实际上没有修改;EL 2.2 于 2009 年 12 月推出)。然而,我同意它需要更新那部分,因为它会让初学者感到困惑。
您找到的答案基于文档提出了自己的观点,但是回答者似乎没有根据问题意识到虽然 binding="#{testController.nodeListener}"
失败了,但 binding="#{testController.nodeListener(event)}"
实际上 有效。这只是不给你通过 ActionEvent
的机会。如果它建议仅使用 binding="#{testController.nodeListener()}"
并以其他方式获取事件信息,例如通过调用 UIComponent#getCurrentComponent()
或什至将 #{component}
作为参数传递,则答案会更好。当然,只有当你真的需要用到它的时候。
<h:commandLink value="link">
<f:actionListener binding="#{bean.someMethod(component)}"/>
</h:commandLink>
public void someMethod(UIComponent component) {
System.out.println("It was called on: " + component); // HtmlCommandLink
}
另请参阅:
- Invoke direct methods or methods with arguments / variables / parameters in EL
- Difference between JSP EL, JSF EL and Unified EL
- Differences between action and actionListener