动作和动作监听器之间的区别

2024-02-05

有什么区别action and actionListener,我应该什么时候使用action versus actionListener?


动作监听器

Use actionListener如果你想要一个钩子before真正的业务行动得到执行,例如记录它,和/或设置附加属性(通过<f:setPropertyActionListener> https://docs.oracle.com/javaee/7/javaserver-faces-2-2/vdldocs-facelets/f/setPropertyActionListener.html),和/或访问调用该操作的组件(可通过ActionEvent http://docs.oracle.com/javaee/7/api/javax/faces/event/ActionEvent.html争论)。因此,纯粹是为了在调用实际业务操作之前进行准备。

The actionListener方法默认具有以下签名:

import javax.faces.event.ActionEvent;
// ...

public void actionListener(ActionEvent event) {
    // ...
}

它应该声明如下,没有任何方法括号:

<h:commandXxx ... actionListener="#{bean.actionListener}" />

注意不能通过额外的EL 2.2 的论点。但是您可以覆盖ActionEvent通过传递和指定自定义参数来完全参数。以下示例有效:

<h:commandXxx ... actionListener="#{bean.methodWithoutArguments()}" />
<h:commandXxx ... actionListener="#{bean.methodWithOneArgument(arg1)}" />
<h:commandXxx ... actionListener="#{bean.methodWithTwoArguments(arg1, arg2)}" />
public void methodWithoutArguments() {}
public void methodWithOneArgument(Object arg1) {}
public void methodWithTwoArguments(Object arg1, Object arg2) {}

请注意无参数方法表达式中括号的重要性。如果它们不存在,JSF 仍会期望使用以下方法:ActionEvent争论。

如果您使用的是 EL 2.2+,那么您可以通过以下方式声明多个操作侦听器方法<f:actionListener binding>.

<h:commandXxx ... actionListener="#{bean.actionListener1}">
    <f:actionListener binding="#{bean.actionListener2()}" />
    <f:actionListener binding="#{bean.actionListener3()}" />
</h:commandXxx>
public void actionListener1(ActionEvent event) {}
public void actionListener2() {}
public void actionListener3() {}

注意括号中的重要性binding属性。如果他们缺席,EL 会令人困惑地抛出一个javax.el.PropertyNotFoundException: Property 'actionListener1' not found on type com.example.Bean,因为binding默认情况下,属性被解释为值表达式,而不是方法表达式。添加 EL 2.2+ 风格的括号可以将值表达式透明地转换为方法表达式。另请参见 a.o.如果 JSF 不支持,为什么我能够将 绑定到任意方法? https://stackoverflow.com/questions/30744949/why-am-i-able-to-bind-factionlistener-to-an-arbitrary-method-if-its-not-supp


action

Use action如果您想执行业务操作并在必要时处理导航。这action方法可以(因此,不是必须)返回一个String它将用作导航案例结果(目标视图)。返回值为null or void将让它返回到同一页面并保持当前视图范围处于活动状态。空字符串或相同视图 ID 的返回值也将返回到同一页面,但会重新创建视图范围,从而销毁任何当前活动的视图范围 bean,并在适用时重新创建它们。

The action方法可以是任何有效的MethodExpression http://docs.oracle.com/javaee/7/api/javax/el/MethodExpression.html,还有使用 EL 2.2 参数的那些,如下所示:

<h:commandXxx value="submit" action="#{bean.edit(item)}" />

用这个方法:

public void edit(Item item) {
    // ...
}

请注意,当您的操作方法仅返回一个字符串时,您也可以在action属性。因此,这是完全笨拙的:

<h:commandLink value="Go to next page" action="#{bean.goToNextpage}" />

使用这种毫无意义的方法返回一个硬编码的字符串:

public String goToNextpage() {
    return "nextpage";
}

相反,只需将该硬编码字符串直接放入属性中即可:

<h:commandLink value="Go to next page" action="nextpage" />

请注意,这反过来表明设计不好:通过 POST 导航。这对用户和 SEO 都不友好。这一切都在什么时候应该使用 h:outputLink 而不是 h:commandLink? https://stackoverflow.com/questions/4317684/when-should-i-use-houtputlink-instead-of-hcommandlink/4317723#4317723并且应该被解决为

<h:link value="Go to next page" outcome="nextpage" />

也可以看看如何在 JSF 中导航?如何使 URL 反映当前页面(而不是上一页) https://stackoverflow.com/questions/15521451/how-to-navigate-in-jsf-how-to-make-url-reflect-current-page-and-not-previous-o.


f:ajax 监听器

从 JSF 2.x 开始,出现了第三种方法,即<f:ajax listener>.

<h:commandXxx ...>
    <f:ajax listener="#{bean.ajaxListener}" />
</h:commandXxx>

The ajaxListener方法默认具有以下签名:

import javax.faces.event.AjaxBehaviorEvent;
// ...

public void ajaxListener(AjaxBehaviorEvent event) {
    // ...
}

在莫哈拉,AjaxBehaviorEvent参数是可选的,下面的效果也很好。

public void ajaxListener() {
    // ...
}

但在 MyFaces 中,它会抛出一个MethodNotFoundException。当您想省略参数时,下面的方法适用于两种 JSF 实现。

<h:commandXxx ...>
    <f:ajax execute="@form" listener="#{bean.ajaxListener()}" render="@form" />
</h:commandXxx>

Ajax 侦听器对于命令组件来说并不是真正有用。它们对于输入和选择组件更有用<h:inputXxx>/<h:selectXxx>。在命令组件中,只需坚持action and/or actionListener为了清晰和更好的自记录代码。而且,像actionListener, the f:ajax listener不支持返回导航结果。

<h:commandXxx ... action="#{bean.action}">
    <f:ajax execute="@form" render="@form" />
</h:commandXxx>

对于解释execute and render属性,前往了解 PrimeFaces 进程/更新和 JSF f:ajax 执行/渲染属性 https://stackoverflow.com/questions/25339056/understanding-primefaces-process-update-and-jsf-fajax-execute-render-attributes.


调用顺序

The actionListeners 总是被调用before the action其顺序与在视图中声明并附加到组件的顺序相同。这f:ajax listener总是被调用before任何动作监听器。所以,下面的例子:

<h:commandButton value="submit" actionListener="#{bean.actionListener}" action="#{bean.action}">
    <f:actionListener type="com.example.ActionListenerType" />
    <f:actionListener binding="#{bean.actionListenerBinding()}" />
    <f:setPropertyActionListener target="#{bean.property}" value="some" />
    <f:ajax listener="#{bean.ajaxListener}" />
</h:commandButton>

将按以下顺序调用方法:

  1. Bean#ajaxListener()
  2. Bean#actionListener()
  3. ActionListenerType#processAction()
  4. Bean#actionListenerBinding()
  5. Bean#setProperty()
  6. Bean#action()

异常处理

The actionListener支持特殊异常:AbortProcessingException http://docs.oracle.com/javaee/7/api/javax/faces/event/AbortProcessingException.html。如果此异常是从actionListener方法,那么 JSF 将跳过任何剩余的操作侦听器和操作方法,并直接继续渲染响应。您不会看到错误/异常页面,但 JSF 会记录它。每当从某个对象抛出任何其他异常时,这也会隐式完成。actionListener。因此,如果您打算因业务异常而通过错误页面来阻止该页面,那么您绝对应该在action method.

如果使用的唯一原因是actionListener就是有一个void方法返回同一页面,那么这是一个坏方法。这action方法也可以完美返回void,与某些 IDE 通过 EL 验证让您相信的相反。请注意,PrimeFaces 展示 http://www.primefaces.org/showcase/这种例子比比皆是actionListener遍布所有地方。这确实是错误的。不要以此为借口自己也这样做。

然而,在 ajax 请求中,需要一个特殊的异常处理程序。这与您是否使用listener的属性<f:ajax>或不。如需解释和示例,请前往JSF ajax 请求中的异常处理 https://stackoverflow.com/questions/27526753/exception-handling-in-jsf-ajax-requests.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动作和动作监听器之间的区别 的相关文章

随机推荐

  • 这个符号~在matlab中起什么作用

    我是物理专业的学生 他们给了我一个 matlab 程序来获得一些结果 matlab 是否在某些时候崩溃并在这一行指出问题 idx min cf 错误信息是 表达式或陈述不正确 可能不平衡 或 我想问 在matlab中做什么 在谷歌搜索中 我
  • Angularjs:加载 HTML 模板时的 HTTP 请求数?

    我刚刚开始学习角度 所以这可能是一个愚蠢的问题 或者我只是错过了一些东西 比如说 我有一个主模板index html 我想在某个时间点插入一个部分模板 这是一个表 因此 我发出一个 HTTP 请求来使用 ajax 加载部分 然后我还发出另一
  • 错误:最低支持的 Gradle 版本为 2.10,尚不支持 Gradle 3.x

    我想要的完整标题 错误 最低支持的 Gradle 版本是 2 10 尚不支持 Gradle 3 x 当前版本是2 4 如果使用 gradle 包装器 请尝试将 gradle wrapper properties 中的 distributio
  • 错误 2002 (HY000): 无法通过套接字 '/var/run/mysqld/mysqld.sock' 连接到本地 MySQL 服务器 (111)

    在 Ubuntu 机器上发出 mysql 命令时出现此错误 错误 2002 HY000 无法通过套接字 var run mysqld mysqld sock 连接到本地 MySQL 服务器 111 该服务未启动并出现以下错误 root be
  • R 中牛区网格的一个共享图例

    我刚刚用包构建了一个网格cowplot 标记 A D 的图 这些图是用包制作的ggplot2 pfour lt ggplot four aes x Concentration y Percentage fill Phenotype geom
  • C# - 检查是否按下了特定键

    我试图检查是否按下了某个键 但收到以下错误消息 错误 1 当前上下文中不存在名称 键盘 错误2 当前上下文中不存在名称 Key 你能告诉我如何修复它吗 public void Main while true if Keyboard IsKe
  • 启动 JettyRun 时排除 Gradle 类路径运行时

    我有基本的 Gradle Web 应用程序项目 它工作正常 但我注意到 Gradle 的运行时类路径包含在 jetty 中 这有可能与 Web 应用程序发生冲突 请注意 下面的 gradle 使用的是稍旧版本的 logback 并且 SL4
  • 连续播放多个声音时有时会保持无声,为什么?

    我遇到了一个奇怪的问题 希望有人能回答它 我有 4x4 按钮 如果我点击它们 每个按钮都会播放 1 秒的短声 我的代码 Button 1 Button findViewById R id button1 Button 1 setOnClic
  • Python 多处理锁

    此多处理代码按预期工作 它创建 4 个 Python 进程 并使用它们打印数字 0 到 39 每次打印后都有延迟 import multiprocessing import time def job num print num time s
  • 在android中使用标签设置和获取片段

    我用 viewpager 创建了一个选项卡布局 一切都很好 除了我需要在特定时刻运行一个方法 所以我需要获取片段实例并运行他们的方法 我是这样创建的 Override protected void onCreate Bundle saved
  • 使用 VsVim 搜索时突出显示会使代码不可读

    我已经使用 VsVim 一段时间了 我对它非常满意 然而 让我烦恼的一件事是当我在 VsVim 中进行任何类型的搜索时 文本的突出显示 例如使用 或标准搜索 我花了几个小时尝试更改 Visual Studios 选项菜单中的字体和颜色 但我
  • QT5:无法在 Windows 中加载 psql 驱动程序

    我想在 Windows 7 中加载 qt5 psql 驱动程序 我已经这样加载库 qDebug lt lt QCoreApplication libraryPaths QString driverName QPSQL QSqlDatabas
  • 移动网站的“链接到 App Store”小部件

    在过去的几个月里 我发现了几个使用某种 小部件 的网站 如果我使用 iPhone 打开具有此小部件的网站 它将显示指向 网站相关 iPhone 应用程序的链接 它看起来像一个简单的 div 包含应用程序名称 评级和链接 该小部件甚至 知道
  • 从 ViewPager 获取不同片段的值

    我正在开发一个应用程序 其中片段是动态生成的 private void setupViewPager ViewPager viewPager adapter new ViewPagerAdapter getSupportFragmentMa
  • Google Sheets:通过 Apps 脚本批量 getRangeByName

    是否可以获得多个按名称范围一通电话 我有一个复杂的函数 需要按名称获取多个范围 而 Spreadsheet getRangeByName name 会显着减慢我的脚本速度 有时这些调用大约需要 2 秒 有时单个调用可能需要大约 45 秒 限
  • svn https: “ra_serf: SSL 通信期间发生错误”

    我知道这与其他帖子的标题相同 但我搜索了又搜索 但找不到解决方案 我在所有机器上从 TortoiseSVN 1 6 升级到 1 8 4 我的主开发机器开始出现此错误 ra serf An error occurred during SSL
  • 具有任意属性的 SPARQL 属性路径查询

    SPARQL 属性路径 http www w3 org TR sparql11 query propertypaths任意长度的查询需要使用特定的属性 我想查询并查找从一个资源开始并以另一个资源结束的任何路径 例如 SELECT p WHE
  • 如何 Iterator::chain 迭代器向量?

    对于给定的一组迭代器 a b c 可以使用以下命令成功链接它们a chain b chain c 由于我尝试编写的 CLI 实用程序提供了路径向量 字符串 dirs a b c d e f 我想使用walkd dir在它们每个上 然后将它们
  • 更改node_modules位置

    有没有办法更改node modules文件夹位置 例如 dir1 dir2 node modules to dir1 dir2 node modules 以下是查看的代码node modules默认文件夹 Module prototype
  • 动作和动作监听器之间的区别

    有什么区别action and actionListener 我应该什么时候使用action versus actionListener 动作监听器 Use actionListener如果你想要一个钩子before真正的业务行动得到执行