【问题标题】:How to get an ajax event to fire from within a p:dialog如何从 p:dialog 中触发 ajax 事件
【发布时间】:2011-08-04 00:34:04
【问题描述】:

所以我今天大部分时间都在试图在组件更改值时调用我的支持 bean 中的方法。如果我的组件在<p:dialog> 之外,一切都会正常工作,但是当嵌套在对话框中时,服务器端永远不会发生。最初我使用<p:calendar> 控件,但注意到它也不适用于简单的inputText。以下示例有效:

<h:panelGrid columns="3">
    <h:outputText value="Start"/>
    <p:inputText id="startOfRange" value="#{myBean.startRange}" valueChangeListener="#{myBean.startChanged}">
        <p:ajax event="change" update="play"/>
    </p:inputText>
    <h:outputText id="play" style="margin-left: 10px;" value="#{myBean.startRange}"/>
</h:panelGrid>

我的支持 bean 方法看起来像

public void startChanged(ValueChangeEvent event) { }

这个方法在 inputText 的一个选项卡之后被调用,但是当像下面这样包装时,这个方法永远不会被调用:

<p:dialog widgetVar="efDlg" zindex="10" appendToBody="true" header="Create Custom Date Range"
      modal="true" height="375" width="450" resizable="false" closable="false" >
<h:panelGrid columns="4">
    <h:outputText value="Start"/>
    <p:inputText id="startOfRange" value="#{myBean.startRange}" valueChangeListener="#{myBean.startChanged}">
        <p:ajax event="change" update="play"/>
    </p:inputText>
    <h:outputText id="play" style="margin-left: 10px;" value="#{myBean.startRange}"/>
    <p:inputText id="endOfRange" value="#{myBean.endRange}" valueChangeListener="#{myBean.endChanged}"/>
</h:panelGrid>
<div class="customRangeButtons">
    <span>
        <p:commandButton value="Cancel" onstart="efDlg.hide();" actionListener="#{myBean.cancelCustomDateRange}" update="pGraphs"/>
    </span>
    <span style="margin-left: 300px;">
        <p:commandButton  value="Ok" type="submit" onstart="efDlg.hide();" action="#{myBean.saveCustomDateRange()}" update="pGraphs"/>
    </span>
</div>    
</p:dialog>

注意我正在使用 Primefaces 2.2.1 和 Mojarra 2.1.0。关于为什么我无法在值更改时调用 startChanged 方法的任何想法?

【问题讨论】:

  • 作为一种解决方法,我关闭了 p:dialog 并手动制作了一个 jQuery 对话框。效果很好。
  • 这是一个明智的选择。即使 2.2.1 是稳定版本,它与对话框组件还有很长的路要走。这些是常见且反复出现的主题,其中某些组件行为在包含在对话框中时是不同的或不存在的。据我所知,这主要与底层 YUI 对话框物理地将 DOM 元素移入和移出表单的方式有关。
  • 我在使用&lt;p:dialog&gt; 时遇到了重大问题。我认为它不适用于同样使用&lt;p:layout&gt; 的 Facelet 页面。不确定您是否也在使用布局。我希望他们能在未来的版本中稳定对话。

标签: jsf-2 primefaces


【解决方案1】:

也许我错了(我家里没有我的项目代码可以验证)但不是这样吗:

<p:ajax event="change" update="play"/>

应该是:

<p:ajax event="valueChange" update="play"/>

我知道大多数 Ajax event 值类似于去掉了“on”的 JavaScript 事件处理程序,但 valueChange 是 JSF Ajax 标记中的一个特殊值。

为了记录,我有时会在一个 inputText 中配对两个 Ajax 子标签,例如:

<p:ajax event="valueChange" process="@this" update="whatever"/>
<p:ajax event="keyUp" process="@this" update="whatever"/>

这将处理输入时的每次击键以及复制和粘贴以及失去对父输入文本的关注。

【讨论】:

  • event="valueChange"确实有特殊的含义。它将呈现为 HTML 文本框、文本区域和下拉列表的 onchange 以及 HTML 单选按钮和复选框的 onclick。但是,在这种特殊情况下,event="change" 与在文本框中使用的效果完全相同。根本原因可能是&lt;p:dialog&gt; 实际上需要自己的&lt;h:form&gt;(不应该嵌套!)。至少,RichFaces 也有类似的问题。
  • 感谢valueChange 的澄清。我认为您对对话和形式的看法可能是正确的。 PrimeFaces 展示示例倾向于以自己的形式拥有对话。另外,我看到 OP 正在使用 appendToBody="true" 属性。对于他们遇到的问题,这似乎是某种解决方法。如果我的页面模板使用&lt;p:layout&gt;,我必须在我的 webapp 中使用它,否则对话框将无法正确呈现。也许是相关的?我不知道。
【解决方案2】:

我也遇到了同样的问题。我也在对话框中使用单个表单并且没有表单。只要我的对话框没有 appendToBody="true" ,输入值和 ajax 和提交就会正确发生。一旦我将该属性添加为 true,为了更好/正确的渲染,输入值将不被接受。

【讨论】:

    猜你喜欢
    • 2012-12-30
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    相关资源
    最近更新 更多