I am having difficulty re-rendering a PrimeFaces Datatable once a cell has been edited. Changing the value in one cell may change entries in the other cells, hence the need to refresh the entire table.
一旦一个单元格被编辑过,我就很难重新绘制一张黄金面孔的数据表。在一个单元格中更改值可能会更改其他单元格中的条目,因此需要刷新整个表。
Here's the JSF page:
这里的JSF页面:
<h:form id="testForm">
<p:outputPanel id="testContainer">
<p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
<p:column headerText="Col1">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{entry.col1}" /></f:facet>
<f:facet name="input"><p:inputText value="#{entry.col1}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Col2">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{entry.col2}" /></f:facet>
<f:facet name="input"><p:inputText value="#{entry.col2}" /></f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
<p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
</p:outputPanel>
</h:form>
And here's the backing bean:
下面是支持bean:
@ManagedBean(name = "tableBean", eager = false)
@ViewScoped
public class TableBean {
public TableBean() {
RowData entry = new RowData("a1", "b1");
entries.add(entry);
entry = new RowData("a2", "b2");
entries.add(entry);
entry = new RowData("a3", "b3");
entries.add(entry);
}
public class RowData {
private String col1;
private String col2;
public RowData(String col1, String col2) {
this.col1 = col1;
this.col2 = col2;
}
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
}
private ArrayList<RowData> entries = new ArrayList<RowData>();
public List<RowData> getData() {
return entries;
}
public void onCellEdit(CellEditEvent event) {
entries.get(event.getRowIndex()).setCol1("Dummy Col 1");
entries.get(event.getRowIndex()).setCol2("Dummy Col 2");
}
}
When including update=":testForm:testContainer" within the cellEdit AJAX event, changing a cell value deletes the datatable on screen and only renders the cell content (along with the button) -- I do not understand why this is. When the update attribute is not specified, the table remains on screen with the active cell updated, but none of the other cells are updated (as to be expected).
当在cellEdit AJAX事件中包含update=":testForm:testContainer"时,更改一个单元格值会删除屏幕上的datatable,只会呈现单元格内容(以及按钮)——我不理解这是为什么。当未指定更新属性时,表仍然在屏幕上,激活的单元格更新,但是其他单元格都没有更新(如预期的那样)。
The desired behaviour can be achieved (in a non-automated way) by not specifying the update attribute within the AJAX cellEdit event and clicking the Redisplay button after editing a cell's value. How can I achieve this in an automated way, and why does the update attribute not work as I expect?
通过不指定AJAX cellEdit事件中的update属性并在编辑单元格值后单击Redisplay按钮,可以实现所需的行为(以非自动化的方式)。我如何以自动化的方式实现这一点,为什么更新属性不能像我预期的那样工作?
I am using PrimeFaces 4.0.
我使用的是prime face 4.0。
4 个解决方案
#1
48
The rowEdit
and cellEdit
events does by design inside the table not update/re-render anything else than the current row, even not when explicitly specified in update
attribute. It's the consequence of PrimeFaces' a bit overzealous attempt to minimize the response size. This makes sense in most of the cases, but not in specifically your case. It's worth an issue report.
rowEdit和cellEdit事件通过在表中进行设计,而不是更新/重新呈现除当前行之外的任何其他内容,甚至在update属性中显式指定时也不会。这是“黄金面孔”的结果,它试图将反应的大小降至最低。这在大多数情况下都是有意义的,但在具体的案例中并不是这样。值得一份报告。
In the meanwhile, until they fix this behavior, your best bet is using <p:remoteCommand>
to invoke the desired listener method and perform a full update of the table.
与此同时,在修复此行为之前,最好的方法是使用
Rewrite
重写
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
...
</p:dataTable>
to
来
<p:remoteCommand name="onCellEdit" action="#{tableBean.onCellEdit}" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" oncomplete="onCellEdit()" />
...
</p:dataTable>
#2
18
The BaLusC solution has not worked directly for me. The onCellEdit needs a CellEditEvent as param. My workaround is as following:
BaLusC解决方案并没有直接为我工作。这个onCellEdit需要一个CellEditEvent作为param。我的工作如下:
<p:remoteCommand name="onCellEdit" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" />
...
</p:dataTable>
#3
5
If none of the solutions worked for you, this worked for me
如果没有一个解决方案适合你,这对我很有效。
<p:dataTable ... id="theId" widgetVar="theWidget" ...>
<p:ajax event="rowEdit" listener="#{...}"
oncomplete="PF('theWidget').filter()"/>
....
I'm calling the filter method on the PF widget on ajax complete, any method that does a "reload" of the table should work, I used filter because my table had column filters.
我调用了在ajax完成的PF小部件上的filter方法,任何执行表“重载”的方法都应该工作,我使用了过滤器,因为我的表有列过滤器。
#4
0
I tested your code. First I moved p:commandButton out of p:outputPanel. Here is modified code:
我测试你的代码。首先,我移动了p:命令按钮从p:outputPanel。这是修改后的代码:
<h:form id="testForm">
<p:outputPanel id="testContainer">
<p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
(...)
</p:dataTable>
</p:outputPanel>
<p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
</h:form>
I think this code doesn't work correctly. if you change anything in table, the p:ajax every time render full table. So, the program load basic data from TableBean constructor and deleted new data.
我认为这段代码不能正常工作。如果在表中更改任何内容,则p:ajax每次呈现全表。因此,程序从TableBean构造函数加载基本数据并删除新数据。
If I omit your p:ajax code there is not disapears any new data from screen. The refreshButton
p:commandButton work correctly.
如果我省略了您的p:ajax代码没有从屏幕上删除任何新数据。命令按钮正确工作。
When including update=":testForm:testContainer" within the cellEdit AJAX event, changing a cell value deletes the datatable on screen and only renders the cell content (along with the button) -- I do not understand why this is.
当在cellEdit AJAX事件中包含update=":testForm:testContainer"时,更改一个单元格值会删除屏幕上的datatable,只会呈现单元格内容(以及按钮)——我不理解这是为什么。
I think it is bad design add update=":testForm:testContainer"
to ajax, because it's update your outputPanel more than as exepted (first time work correctly, second time couldn't edit cell, because the program update to many times table).
我认为这是一个糟糕的设计,添加update=":testForm:testContainer"到ajax,因为它更新您的outputPanel超过了exepted(第一次正确工作,第二次不能编辑单元格,因为程序更新到很多次表)。
I don't know what is your goal. If you want render table without a commandButton, then could you specify one javascript event or p:message and this disappear you can render table.
我不知道你的目标是什么。如果您希望在没有命令按钮的情况下呈现表,那么您可以指定一个javascript事件或p:消息和这个消失您可以呈现表。
I think if you omit update in p:ajax or specify update of one p:message, and move p.commandButton out of testContainer
your code start work correctly.
我认为,如果您省略了p:ajax或指定一个p:消息的更新,并将p. commandbutton从testContainer中移出,您的代码就可以正常工作了。
#1
48
The rowEdit
and cellEdit
events does by design inside the table not update/re-render anything else than the current row, even not when explicitly specified in update
attribute. It's the consequence of PrimeFaces' a bit overzealous attempt to minimize the response size. This makes sense in most of the cases, but not in specifically your case. It's worth an issue report.
rowEdit和cellEdit事件通过在表中进行设计,而不是更新/重新呈现除当前行之外的任何其他内容,甚至在update属性中显式指定时也不会。这是“黄金面孔”的结果,它试图将反应的大小降至最低。这在大多数情况下都是有意义的,但在具体的案例中并不是这样。值得一份报告。
In the meanwhile, until they fix this behavior, your best bet is using <p:remoteCommand>
to invoke the desired listener method and perform a full update of the table.
与此同时,在修复此行为之前,最好的方法是使用
Rewrite
重写
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
...
</p:dataTable>
to
来
<p:remoteCommand name="onCellEdit" action="#{tableBean.onCellEdit}" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" oncomplete="onCellEdit()" />
...
</p:dataTable>
#2
18
The BaLusC solution has not worked directly for me. The onCellEdit needs a CellEditEvent as param. My workaround is as following:
BaLusC解决方案并没有直接为我工作。这个onCellEdit需要一个CellEditEvent作为param。我的工作如下:
<p:remoteCommand name="onCellEdit" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" />
...
</p:dataTable>
#3
5
If none of the solutions worked for you, this worked for me
如果没有一个解决方案适合你,这对我很有效。
<p:dataTable ... id="theId" widgetVar="theWidget" ...>
<p:ajax event="rowEdit" listener="#{...}"
oncomplete="PF('theWidget').filter()"/>
....
I'm calling the filter method on the PF widget on ajax complete, any method that does a "reload" of the table should work, I used filter because my table had column filters.
我调用了在ajax完成的PF小部件上的filter方法,任何执行表“重载”的方法都应该工作,我使用了过滤器,因为我的表有列过滤器。
#4
0
I tested your code. First I moved p:commandButton out of p:outputPanel. Here is modified code:
我测试你的代码。首先,我移动了p:命令按钮从p:outputPanel。这是修改后的代码:
<h:form id="testForm">
<p:outputPanel id="testContainer">
<p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
(...)
</p:dataTable>
</p:outputPanel>
<p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
</h:form>
I think this code doesn't work correctly. if you change anything in table, the p:ajax every time render full table. So, the program load basic data from TableBean constructor and deleted new data.
我认为这段代码不能正常工作。如果在表中更改任何内容,则p:ajax每次呈现全表。因此,程序从TableBean构造函数加载基本数据并删除新数据。
If I omit your p:ajax code there is not disapears any new data from screen. The refreshButton
p:commandButton work correctly.
如果我省略了您的p:ajax代码没有从屏幕上删除任何新数据。命令按钮正确工作。
When including update=":testForm:testContainer" within the cellEdit AJAX event, changing a cell value deletes the datatable on screen and only renders the cell content (along with the button) -- I do not understand why this is.
当在cellEdit AJAX事件中包含update=":testForm:testContainer"时,更改一个单元格值会删除屏幕上的datatable,只会呈现单元格内容(以及按钮)——我不理解这是为什么。
I think it is bad design add update=":testForm:testContainer"
to ajax, because it's update your outputPanel more than as exepted (first time work correctly, second time couldn't edit cell, because the program update to many times table).
我认为这是一个糟糕的设计,添加update=":testForm:testContainer"到ajax,因为它更新您的outputPanel超过了exepted(第一次正确工作,第二次不能编辑单元格,因为程序更新到很多次表)。
I don't know what is your goal. If you want render table without a commandButton, then could you specify one javascript event or p:message and this disappear you can render table.
我不知道你的目标是什么。如果您希望在没有命令按钮的情况下呈现表,那么您可以指定一个javascript事件或p:消息和这个消失您可以呈现表。
I think if you omit update in p:ajax or specify update of one p:message, and move p.commandButton out of testContainer
your code start work correctly.
我认为,如果您省略了p:ajax或指定一个p:消息的更新,并将p. commandbutton从testContainer中移出,您的代码就可以正常工作了。