【问题标题】:JSF(Primefaces) update from within a tableJSF(Primefaces)从表中更新
【发布时间】:2013-12-16 16:52:24
【问题描述】:

我有一个数据表,其中包含删除行的按钮,之后我想刷新该表。除了删除最后一项的情况外,刷新工作正常。我相信这是因为 rendered 属性在 ajax 更新时行为不端。 这一切都在一个复合组件中,数据表是有条件地呈现的,它看起来像这样:

<p:dataTable id="#{cc.attrs.id2}_resultTable"
             value="#{cc.attrs.listData}"
             var="f"
             rendered="#{cc.attrs.list and not empty cc.attrs.listData}"
             rowKey="#{f.code}">
    ...columns
    <p:column>
        <p:commandButton action="#{myBB.removeItem}"
                         update="#{cc.attrs.id2}_resultTable">
            <f:setPropertyActionListener value="#{f}" target="#{myBB.selected}"/>
        </p:commandButton>
    </p:column>
</p:dataTable>

这很好用,除非我从列表中删除最后一项(并希望表格消失)。通过 ajax 显示表格不是问题,因为我添加的项目也没有提交,并且表格在添加第一个项目后正确显示。

我试图用 ID 将表格括在 h:panelgroup id="#{cc.attrs.id2}_resultPanel" 中并更新它,但我得到了这个异常:

Cannot find component with expression "test_resultPanel" 
referenced from "mainForm:j_idt111:test_resultTable:0:j_idt187".

我也许可以使用组件的完整路径,但这有点问题,因为它是一个复合组件。

有趣的想法是,更新是从表格外部进行的。但是当我将它移到表格中的列时,它没有。

【问题讨论】:

  • 您可以将 &lt;p:dataTable&gt; 放在&lt;h:panelGroup layout="block" id="tableDiv"&gt; 中并尝试更新 div 即 tableDiv 而不是 &lt;p:dataTable&gt;
  • Diganta:我试过了(见问题结尾)
  • 您可以通过:j_idt111:test_resultTable这种方式更新复合组件。用你自己的id替换生成的id
  • 这个 j_idt111 在复合组件之外,所以我无法控制它。但无论如何它不起作用。看起来好像我无法在更新中引用除表本身之外的任何内容:```无法找到从“mainForm:j_idt128:test_resultTable:0:j_idt145”引用的表达式“:j_idt128:test_resultTable”的组件。```跨度>
  • 我认为问题在于,当执行操作并更新数据时,commandButton 不再出现在视图中。

标签: ajax jsf primefaces


【解决方案1】:

NeplatnyUdaj 可能对原因有这个权利,它很可能是渲染属性。我通常用来解决这个问题的解决方案是简单地创建一组包装对象,然后刷新整个表。

你的模型可能看起来像 ->

  List<Wrapper> data = ....;
  public class Wrapper implements Serializable
  {
      properties....
     public void onAction(ActionEvent evt) { removeMeFromList(); //..do something }
  }

在视图中,您只需直接引用包装器对象:

      <p:dataTable var="data" id="table"> ...
         <p:column>
           <p:commandButton actionListener="#{data.onAction}" update="table"/> 
           //Ajax updates here via the "Wrapper" object. 
           //Also, when there's complex business logic I find this 
           //easier to read (purely my preference).
         </p:column>
      ....

这并不优雅,但实际上很容易使用(而且,如果您不担心内存中有很多对象,这是一种简单的处理方法)。因为您的动作监听器会在包装器对象上触发,所以您不必担心它何时触发,所有更新都发生在 bean 中,然后您的表会使用新模型进行更新。

在这种情况下,我会根据 List 的大小来标记渲染,但这都是基于实现的。

祝你好运,希望对你有所帮助。

【讨论】:

  • 感谢您的输入,但隐藏表格的重要性并不能证明对代码进行如此大的更改是合理的。但是通常当我放弃时,我想出了简单且有效的解决方案(实际上它发生在我写这篇文章时)。我只是从 commandButton 调用p:remoteCommand 并从那里更新封闭的h:panelGroup :)
  • 这是一个完全有效的解决方法。我在上面提出的解决方案通常是 PrimeFaces 的一个非常可靠的设计模式(树模型等......),因为我发现你遇到这些边缘情况的频率比你喜欢的要多。我将把它归档作为处理它的技巧 - 感谢您的回复。
猜你喜欢
  • 1970-01-01
  • 2021-02-24
  • 2012-12-04
  • 1970-01-01
  • 2013-05-11
  • 2014-06-11
  • 1970-01-01
  • 2012-07-26
  • 2012-10-11
相关资源
最近更新 更多