p:dataTable 中的数据过多导致 row/cell 编辑提交损坏
Too much data in p:dataTable results in broken row/cell edit submits
我一直在使用数据表来允许用户输入和编辑大量数据,但发现一旦达到大量(但不确定)的列和行,表单就无法提交,并切断与服务器的所有形式的通信(不相关的按钮、ajax 等),直到执行页面刷新。
这是我的 computer/browser 的限制,还是对能够在数据表中显示的可编辑数据的最大数量有硬编码限制?这可能是因为表单中输入字段的数量有最大限制吗?
是对我的数据表使用分页器的唯一解决方案吗?
以下是一个示例,如果有太多 rows/columns.
,将无法(对我而言)进行编辑
<h:form>
<p:dataTable var="_var" value="#{bean.values}" editable="true">
<p:column headerText="Value">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{_var.value}" /></f:facet>
<f:facet name="input"><p:inputText value="#{_var.value}" /></f:facet>
</p:cellEditor>
</p:column>
<!-- Copy and paste this^ column 15 times -->
<p:column>
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
好的,我找到了 solution。
显然每个输入都作为 GET/POST 参数发送,并且服务器上的默认限制为 512 以防止 DoS 攻击。
不幸的是,Primefaces 似乎没有显示此错误,因此很难找到。
编辑:如果日志记录设置为正确的级别,它会显示错误。 F12开发者工具调试日志中也显示该错误。
简而言之,您必须前往您的服务器 standalone.xml
并添加:
<property name="org.apache.tomcat.util.http.Parameters.MAX_COUNT" value="10000"/>
在<system-properties>
之下
编辑
我拒绝放弃比发送数千个参数更好的解决方案,并重新审视了这个问题。
似乎 PrimeFaces 5.2 添加了 <p:ajax partialSubmitFilter="">
属性,允许过滤您想要的输入。这对我不起作用,因为我无法仅使用此方法将提交的数据缩小到行。
相反,我决定重写 PrimeFaces.ajax.Request.send
函数,如下所示:
var pfsend = PrimeFaces.ajax.Request.send;
PrimeFaces.ajax.Request.send = function(cfg) {
if (cfg.event === 'rowEdit' || cfg.event === 'rowEditCancel') {
// This is an operation on a datatable row. Filter for only that row
cfg.partialSubmitFilter = '[data-ri=' + cfg.ext.params[0].value + '] :input';
}
pfsend(cfg); // Run the original function
};
这样,cfg的第一个参数(正在编辑的行)的值被用作查找属性data-ri
设置为该值的元素的值(行).
请注意,这 确实 要求您拥有 primefaces 5.2,但对于旧版本,可以通过覆盖整个包并巧妙地将类似的行放在右侧来实现相同的目的相同功能的地方(注意 cfg.partialSubmitFilter 将不存在)。
使用行或单元格编辑器时,指示 cellEdit
事件使用 partialSubmit="true"
。
<p:dataTable ... editable="true">
<p:ajax event="cellEdit" process="@this" partialSubmit="true" />
...
</p:dataTable>
这将仅发送 process
属性(行或单元格本身)涵盖的输入字段,而不是每个输入字段。
另请参阅:
我找到了更优雅的解决方案,没有覆盖函数 PrimeFaces.ajax.Request.send 并且仍然只在 rowEdit 事件上发生。
首先定义javascript函数:
function sendOnlyEditedRow(cfg) {
cfg.partialSubmitFilter = "[data-ri=" + cfg.ext.params[0].value + "] :input";
}
然后在onstart回调中调用:
<p:ajax onstart="sendOnlyEditedRow(cfg)" event="rowEdit" listener="#{cc.attrs.detectedFormations.confirmDetectedFormation(i)}"
process="@this detectedFormations" update="detectedFormations"
partialSubmit="true" />
我一直在使用数据表来允许用户输入和编辑大量数据,但发现一旦达到大量(但不确定)的列和行,表单就无法提交,并切断与服务器的所有形式的通信(不相关的按钮、ajax 等),直到执行页面刷新。
这是我的 computer/browser 的限制,还是对能够在数据表中显示的可编辑数据的最大数量有硬编码限制?这可能是因为表单中输入字段的数量有最大限制吗?
是对我的数据表使用分页器的唯一解决方案吗?
以下是一个示例,如果有太多 rows/columns.
,将无法(对我而言)进行编辑<h:form>
<p:dataTable var="_var" value="#{bean.values}" editable="true">
<p:column headerText="Value">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{_var.value}" /></f:facet>
<f:facet name="input"><p:inputText value="#{_var.value}" /></f:facet>
</p:cellEditor>
</p:column>
<!-- Copy and paste this^ column 15 times -->
<p:column>
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
好的,我找到了 solution。
显然每个输入都作为 GET/POST 参数发送,并且服务器上的默认限制为 512 以防止 DoS 攻击。
不幸的是,Primefaces 似乎没有显示此错误,因此很难找到。
编辑:如果日志记录设置为正确的级别,它会显示错误。 F12开发者工具调试日志中也显示该错误。
简而言之,您必须前往您的服务器 standalone.xml
并添加:
<property name="org.apache.tomcat.util.http.Parameters.MAX_COUNT" value="10000"/>
在<system-properties>
编辑
我拒绝放弃比发送数千个参数更好的解决方案,并重新审视了这个问题。
似乎 PrimeFaces 5.2 添加了 <p:ajax partialSubmitFilter="">
属性,允许过滤您想要的输入。这对我不起作用,因为我无法仅使用此方法将提交的数据缩小到行。
相反,我决定重写 PrimeFaces.ajax.Request.send
函数,如下所示:
var pfsend = PrimeFaces.ajax.Request.send;
PrimeFaces.ajax.Request.send = function(cfg) {
if (cfg.event === 'rowEdit' || cfg.event === 'rowEditCancel') {
// This is an operation on a datatable row. Filter for only that row
cfg.partialSubmitFilter = '[data-ri=' + cfg.ext.params[0].value + '] :input';
}
pfsend(cfg); // Run the original function
};
这样,cfg的第一个参数(正在编辑的行)的值被用作查找属性data-ri
设置为该值的元素的值(行).
请注意,这 确实 要求您拥有 primefaces 5.2,但对于旧版本,可以通过覆盖整个包并巧妙地将类似的行放在右侧来实现相同的目的相同功能的地方(注意 cfg.partialSubmitFilter 将不存在)。
使用行或单元格编辑器时,指示 cellEdit
事件使用 partialSubmit="true"
。
<p:dataTable ... editable="true">
<p:ajax event="cellEdit" process="@this" partialSubmit="true" />
...
</p:dataTable>
这将仅发送 process
属性(行或单元格本身)涵盖的输入字段,而不是每个输入字段。
另请参阅:
我找到了更优雅的解决方案,没有覆盖函数 PrimeFaces.ajax.Request.send 并且仍然只在 rowEdit 事件上发生。 首先定义javascript函数:
function sendOnlyEditedRow(cfg) {
cfg.partialSubmitFilter = "[data-ri=" + cfg.ext.params[0].value + "] :input";
}
然后在onstart回调中调用:
<p:ajax onstart="sendOnlyEditedRow(cfg)" event="rowEdit" listener="#{cc.attrs.detectedFormations.confirmDetectedFormation(i)}"
process="@this detectedFormations" update="detectedFormations"
partialSubmit="true" />