【问题标题】:JSF Ajax rerender <h:textInput ...> on ChangeJSF Ajax 在更改时重新渲染 <h:textInput ...>
【发布时间】:2013-08-16 14:04:38
【问题描述】:

我正在尝试让 h:textInput 在更改时重新呈现,我已尝试使用 a4j:ajax 和 f:ajax。

使用 a4j:ajax 时:

<h:panelGroup id="xyzPG">

<ui:repeat var="var" ... >
   ...
  <h:inputText id="#{idController.getIdXYZ(var.id)}" 
   value="#{someModel.value}" 
   size="3" 
   styleClass="#{errorController.getErrorStateStyleId(idController.getIdXYZ())}">
   <a4j:ajax event="change" render="xyzPG" listener="#{listener.doSomeStuff}" />
  </h:inputText> 
  ...
</ui:repeat>  
</h:panelGroup>

这是第一次工作,在面板第一次更新后它停止更新模型并且侦听器也没有被调用。然而,渲染被触发,导致显示旧值。

现在,当我将 a4j:ajax 替换为 f:ajax 时,我收到错误消息,指出在 xyzInput 中找不到 id xyzPG。

<f:ajax event="change" render="@this" listener="#{listener.doSomeStuff}" />

当我尝试将重新渲染限制为 inputText 时,它总是会更新模型并调用侦听器,但是不会重新渲染 h:inputText。

我已经尝试在 inputText 周围放置另一个 panelGroup,但这也没有用。

我们不使用 h:dataTable 的原因是因为我们必须生成一个具有以下布局的 Table:

---------------------------- 
| dataSet1     | dataSet 2 |
----------------------------
| dataSet3     | dataSet 4 |
etc...

因此我们使用 ui:repeat 的 offset 和 step 属性。

【问题讨论】:

  • 您是否尝试过其他事件,例如bluronkeyup 等...?
  • 您对id 的动态使用让我的眼睛流血了。您可以使用以下答案避免与此相关的所有麻烦:stackoverflow.com/a/7312979/785663认为您遇到了视图与渲染时间问题。没有c:repeat - 你有ui:repeatc:forEach 吗?如果是后者,另请参阅obligatory link
  • wupps - 典型错误 - 正如您正确地指出它的 ui:repeat 这就是当您编写代码而不是复制原始代码时会发生的情况。关于动态 id - 我也不太满意,但由于项目特定的限制,这个决定是由项目架构师做出的,所以我们坚持这样做。
  • 我已经添加了关于我们为什么使用 ui:repeat 的解释

标签: jsf jsf-2


【解决方案1】:

没有看到你的支持 bean 代码,我认为你应该使用

<h:inputText id="#{idController.idXYZ}"

而不是

<h:inputText id="#{idController.getIdXYZ()}" 

【讨论】:

  • id 已正确解析 - 当您使用带有 () 或 (param) 的 el 表示法时,您必须编写包括 get 在内的完整方法。
【解决方案2】:
  1. 根据设计,您不能使用像&lt;ui:repeat/&gt; 这样的渲染时标签动态生成id 属性
  • Compile-time V Render-time tags

    出于视图构造和 ajax 更新的目的,组件的ids 必须在视图构造期间在呈现视图之前可用。 &lt;ui:repeat/&gt; 已经满足了它的子组件的唯一性。但是,如果您需要控制 id,则需要使用编译时标记处理程序,例如 &lt;c:forEach/&gt;:

      <c:forEach items="#{idController.itemsList}" var="theVar">
         <h:inputText id="#{idController.getIdXYZ(theVar.id)}" value="#{someModel.value}" size="3" styleClass="#{errorController.getErrorStateStyleId(idController.getIdXYZ())}">
             <a4j:ajax event="change" render="xyzPG" listener="#{listener.doSomeStuff}" />
         </h:inputText> 
      <c:forEach/>
    
  1. 您不太可能从&lt;ui:repeat/&gt; 中访问xyzPG,因为&lt;ui:repeat/&gt; 也是一个命名容器,就像&lt;h:panelGrid/&gt; 等等。 ajax 更新适用于 Richfaces,因为它们为此类用例做出了特殊规定。 &lt;f:ajax/&gt; 但是不会容忍它。 xyzPG 超出了 &lt;ui:repeat/&gt; 的范围,因此要访问该组件,您需要使用合格的命名约定:

      <f:ajax event="change" render=":form1:xyzPG" listener="#{listener.doSomeStuff}"/>
    

这假定xyzPG 直接包含在&lt;h:form id="form1"/&gt;

【讨论】:

  • 感谢您的详细回答。我设法通过简单地使用 rich:datagrid 解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 2014-03-27
  • 1970-01-01
  • 1970-01-01
  • 2020-04-23
  • 2021-01-27
  • 2010-11-12
  • 2011-02-06
  • 2016-12-30
相关资源
最近更新 更多