JSF(Primefaces)从表中更新

时间:2013-12-16 16:52:24

标签: ajax jsf primefaces

我有一个数据表,其中包含删除行的按钮,之后我想刷新该表。刷新工作正常,除了我删除最后一项的情况。我相信这是因为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".

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

有趣的是,更新可以从表外部进行。但是,当我将它移动到表格中的列时,它不会。

1 个答案:

答案 0 :(得分:1)

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

您的模型可能看起来像 - &gt;

  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的大小标记渲染,但这都是基于实现。

祝你好运,希望这能帮到你。