【问题标题】:commandButton inactive after ajax renderingajax渲染后commandButton无效
【发布时间】:2013-07-04 13:44:32
【问题描述】:

我对这两个命令按钮有问题:加入和离开。

如果我点击离开,我想隐藏加入,反之亦然。

当我将 ajax 设置为 false 时,没有问题(但所有页面都在刷新,我觉得这不是最佳的)。

但是,当 ajax 属性为 true 并进行特定更新时(参见代码中的注释),渲染效果很好,但新按钮似乎变得不活动。如果我点击它,什么也不会发生(好吧,似乎是 actionListener 触发器,但视图没有刷新,我必须手动刷新才能看到差异)

感谢阅读。

<h:form id="formWaitingList" rendered="#{connexion.connected}" >
    <p:commandButton id="Join"  
                    actionListener = "#{connexion.joinWaitingList()}"
                    rendered="#{!connexion.waiting}"
                    ajax="false"
               <!-- ajax="true"
                    update="Join,Leave"-->
                    value="Join"/>

   <p:commandButton id="Leave" 
                    value="Leave"
                    ajax="false"
               <!-- ajax="true"
                    udpate="Join,Leave"-->
                    rendered="#{connexion.waiting}"
                    actionListener ="#{connexion.leaveWaitingList()}" />
</h:form>

【问题讨论】:

  • 你应该使用 update="@form" 因为buttons with render=false 不会出现在html生成的代码中,所以你不能直接更新它们。

标签: jsf primefaces updates renderer commandbutton


【解决方案1】:

您似乎对 HTML/JavaScript 并不完全熟悉。你知道,JSF 基本上是一个 HTML/JavaScript(/CSS) 代码生成器。在 JavaScript 中 Ajax 更新的工作方式基本上是这样的:

  • 通过XMLHttpRequest 向 JSF 发送 ajax 请求后,检索一个 XML 响应,其中包含需要更新的所有元素及其客户端 ID。
  • 对于每个要更新的元素,使用document.getElementById(clientId) 在当前的 HTML DOM 树中找到它。
  • 用 ajax XML 响应中指定的新元素替换该元素。

然而,如果一个 JSF 组件因为rendered="false" 而没有生成它的 HTML 表示,那么在 HTML DOM 树中就没有任何东西可以被找到和替换。这完全解释了您“看到”的症状。

您基本上需要将有条件呈现的 JSF 组件包装在其 HTML 表示始终呈现的组件中,然后在 ajax 更新中引用它。

例如,

<h:form>
    ...

    <h:panelGroup id="buttons">
         <p:commandButton ... update="buttons" rendered="#{condition}" />
         <p:commandButton ... update="buttons" rendered="#{not condition}" />
    </h:panelGroup>
</h:form>

另见:

【讨论】:

  • 哦,太好了,它工作正常!我看过你的一篇关于用面板包装的帖子,但我不是只包装按钮,而是包装了表单>
  • @BalusC 嗨,BalusC,如果您不介意,我有一个问题。我刚才在玩 OP 代码(也是 ajax 的新手),我做了这个 &lt;p:commandButton id="Join" rendered = "conditionforButton1" actionListener = "#{connexion.joinWaitingList()}" value="Join"/&gt;(按钮 #2 有一个单独的 rendered 值)。在按钮#1 的动作监听器中,我将第二个按钮的rendered 属性设置为true,将第一个按钮设置为false。第二个按钮确实出现了,但是当我单击时,actionListener 从未被触发。为什么会这样?
  • @BalusC 我猜我没有看到完整的图片。根据您的回答,我的理解是,如果rendered 为假,则没有为按钮 #2 生成 HTML,因此它永远不会更新,因为...好吧,它一开始就不存在,但在我的情况下,按钮 #2 确实显示了上...我会停在这里。如果我的回答含糊/混淆,请告诉我,我会发布一个官方问题。谢谢。
  • @Andy:条件需要查看范围。另见stackoverflow.com/questions/2118656/…的第 5 点
  • @BalusC 这是视图范围 :(。让我再读一遍这两个答案。
猜你喜欢
  • 2012-07-19
  • 2011-12-11
  • 1970-01-01
  • 2018-05-31
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
  • 2022-08-19
  • 1970-01-01
相关资源
最近更新 更多