JSF2 commandButton 操作未在更新的片段中调用
Posted
技术标签:
【中文标题】JSF2 commandButton 操作未在更新的片段中调用【英文标题】:JSF2 commandButton action not invoked in an updated fragment 【发布时间】:2015-04-29 22:22:30 【问题描述】:我在表单中有命令按钮。那些在页面加载时呈现的是调用动作,
但是<p:fragment>
标记中的那两个在回发时呈现并且不起作用。
<h:form>
<p:commandButton action="#bean.actionA()"/>
<p:commandButton actionListener="#bean.actionB()"/>
<p:fragment rendered="#not empty bean.field">
<p:commandButton action="#bean.actionA()"/>
<p:commandButton actionListener="#bean.actionB()"/>
</p:fragment>
<ui:include ..>
...
<p:commandLink update="@form">
<i class="fa fa-folder"></i>
<f:setPropertyActionListener value="#data.document" target="#bean.field" />
</p:commandLink>
</ui:include>
</h:form>
我是 JSF 的菜鸟。我知道这个问题与 JSF 生命周期有关,但我找不到可行的解决方案。
我的 bean
是视图范围,我使用 primefaces 5.1。
这是假设工作还是我使用了错误的方法来显示/隐藏按钮?
谢谢。
编辑:
经过一些测试,它接缝即使在调用操作时也会在带有null==bean.field
的 bean 上调用。
这对我来说没有意义,因为在更新完成并显示隐藏按钮后,我得到了渲染值 #bean.field.name
。
我错过了什么?
将update=@form
更改为update=@all
时效果相同。
感谢任何帮助。
我的具有会话范围的 bean 很喜欢这个。在这种情况下,SessionScoped
按钮正在工作。为什么视图范围不够?
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.faces.view.ViewScoped;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
//TODO: change to @ViewScoped
@ManagedBean(name="bean")
@SessionScoped
public class Bean extends BeanBase
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = LogManager.getLogger(Bean.class.getName());
@PostConstruct
protected void init()
super.init();
public void actionA()
LOGGER.debug("Action A triggerd!");
public void actionB( ActionEvent event)
LOGGER.debug("Action B event triggerd!");
super.edit(event);
【问题讨论】:
@stg 还是同样的问题。当我用p:outputPanel
或f:subview
替换p:fragment
时,按钮不会触发。
正如here 所写,它应该适用于“update=@form”。这正是我正在做的。我的表单更新是从复合组件调用的。但它的工作原理是显示隐藏的按钮。但是按钮操作没有正确设置。
@stg 我如何测试那个和哪个表达式。如何找到它? Bean 在视图范围内。它适用于工作按钮的操作,
@stg 我已经用bean.field
setter 和 update 调用更新了代码。我尝试了日志记录,但我不知道如何将它们分成 JSF 阶段。在页面加载时,我有 12 个 'bean.field' getter,其中 3 个为空。单击按钮时,我有 3 个 null 返回 getter cal。不同之处仅在于在一种情况下触发了对 bean 的操作。希望这会有所帮助。
它接缝即使在调用操作时也会在带有null==bean.field
的bean 上调用。我错过了什么?
【参考方案1】:
首先,p:fragment
标签应该用于在 AJAX 调用期间部分提交和处理表单的片段,而无需直接在相应的组件上明确定义此行为。如果您只想对一组组件进行强制渲染,最好只使用 p:outputPanel
。
但是这里导致问题的原因是,不仅在必须呈现表单时评估呈现的属性,而且在处理表单时也会评估。如果由于某种原因,渲染属性中的表达式现在被评估为false
,则处理表单将停止并且不会调用操作。只是出于安全原因。
在您的情况下,field
在表单被预处理时被评估为null
,因此您的 commandButton 父级的呈现属性被评估为false
,这就是不调用操作方法的原因。
这样做的原因是,您的 ManagedBean 的范围由于某种原因太小和/或在渲染响应阶段后被销毁,因此,当您单击命令按钮时,您完全使用从未设置过 field
值的托管 bean 的新实例。
正如您所料,您的 ManagedBean 很可能在请求范围而不是视图范围内。检查您是否使用了正确的注释,将 Bean 置于正确的范围内,并且您没有混淆 JSF 和 CDI 注释。
【讨论】:
我使用@ViewScoped
注解和import javax.faces.view.ViewScoped;
。我认为应该这样做。好吧,它没有。你是对的,范围应该更大。当我更改为SessionScoped
时,它可以工作。为什么视图范围不够?
@ViewScoped 应该足够广泛,如果你正确使用它的话。出于某种原因,您的 ViewScoped bean 无论如何都会被销毁。确保在单击 commandLink 时进行真正的 AJAX 调用而没有任何重定向。但是发布的代码中不存在您的问题。如果您希望我们调查您的 VewScoped bean 行为的原因,您必须提供一个完整的工作示例,说明问题真正发生的位置。
在这种情况下,我可以向您发送一小部分活动代码。很少有文件可以看。目前从项目中制作一个工作示例非常耗时。
我添加了一张图片,显示没有使用重定向。如果您有时间,我可以给您发送一个包含一些代码片段的 zip 文件供您查看。感谢您的努力。以上是关于JSF2 commandButton 操作未在更新的片段中调用的主要内容,如果未能解决你的问题,请参考以下文章
h:button 和 h:commandButton 之间的区别