java PrimeFaces 3.0 - f:ajax Ajax Group 没有从 p:commandButton 或 p:commandLink 接收事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6308969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PrimeFaces 3.0 - f:ajax Ajax Group not receiving events from p:commandButton or p:commandLink
提问by Jim Tough
I am trying to integrate PrimeFaces 3.0 into my JSF 2.0 project. I've created some example code to try and get a PrimeFaces <p:dataTable>
with a delete button/link in a column for each row. I want the delete action to trigger an Ajax refresh of the table (my current code triggers a render of the enclosing form using @form).
我正在尝试将 PrimeFaces 3.0 集成到我的 JSF 2.0 项目中。我已经创建了一些示例代码来尝试<p:dataTable>
在每一行的列中获取一个带有删除按钮/链接的 PrimeFaces 。我希望删除操作触发表的 Ajax 刷新(我当前的代码使用 @form 触发封闭表单的呈现)。
My problem is that the PrimeFaces components do not appear to be firing events that can be handled by the core JSF <f:ajax>
tag. I am using <f:ajax>
as an Ajax Group that encloses the <p:dataTable>
as well as another command button.
我的问题是 PrimeFaces 组件似乎不会触发可由核心 JSF<f:ajax>
标记处理的事件。我使用<f:ajax>
的 Ajax 组包含<p:dataTable>
一个命令按钮和另一个命令按钮。
If I implement this purely using core JSF elements (<h:dataTable>
, <h:commandButton>
, etc.) everything works as expected. Pardon the ugly output, but I'm not going to waste time on CSS styling for my example code.
如果我实现这个纯粹使用核心JSF元素(<h:dataTable>
,<h:commandButton>
等)一切正常。请原谅丑陋的输出,但我不会在示例代码的 CSS 样式上浪费时间。
Here is the code for the core JSF implementation page:
下面是核心 JSF 实现页面的代码:
<h:form id="dataTableForm">
<f:ajax
listener="#{dataTableTestBean.processAjaxBehavior}"
event="action"
render="@form :messages :ajaxRenderTargetsInTemplate">
<h:panelGroup id="dataTablePanelGroup">
<h:commandLink
id="commandLinkAddRow"
value="Add Sample Row"
actionListener="#{dataTableTestBean.handleAddDataTableRow}" />
<h:commandButton
id="commandButtonAddRow"
value="Add Sample Row"
actionListener="#{dataTableTestBean.handleAddDataTableRow}" />
<sandbox:dataTableCC
id="dataTableCC"
valueList="#{dataTableTestBean.dataTableList}" />
</h:panelGroup>
</f:ajax>
<h:panelGroup rendered="#{empty dataTableTestBean.dataTableList}">
<h3>No Records To Display</h3>
</h:panelGroup>
<h:commandButton
id="commandButtonBackToStartPage"
value="#{bundle.backToStartPage}"
action="start"
immediate="true" />
</h:form>
Here is the code for the core JSF implementation CC:
下面是核心 JSF 实现 CC 的代码:
<composite:implementation>
<h:dataTable
id="theDataTable"
rendered="#{not empty cc.attrs.valueList}"
value="#{cc.attrs.valueList}"
var="row"
emptyMessage="#{bundle.dataTableEmptyMessage}">
<f:facet name="header">#{bundle.dataTableHeader}</f:facet>
<h:column id="columnDeleteButton">
<h:commandLink
id="commandLinkDelete"
value="Delete"
action="#{dataTableTestBean.actionDeleteDataTableRow(row)}" />
</h:column>
<h:column>
<h:commandButton
alt="#{bundle.delete}"
image="#{resource['images/onebit_33_24x24.gif']}"
action="#{dataTableTestBean.actionDeleteDataTableRow(row)}" />
</h:column>
<h:column sortBy="#{row.name}">
<f:facet name="header">
#{bundle.columnHeaderName}
</f:facet>
<h:outputText value="#{row.name}" />
</h:column>
<h:column sortBy="#{row.rank}">
<f:facet name="header">
#{bundle.columnHeaderRank}
</f:facet>
<h:outputText value="#{row.rank}" />
<f:facet name="footer">
#{bundle.columnFooterRank}
</f:facet>
</h:column>
<h:column sortBy="#{row.serialNumber}">
<f:facet name="header">
#{bundle.columnHeaderSerialNumber}
</f:facet>
<h:outputText value="#{row.serialNumber}" />
<f:facet name="footer">
#{bundle.columnFooterSerialNumber}
</f:facet>
</h:column>
<f:facet name="footer">#{bundle.dataTableFooter}</f:facet>
</h:dataTable>
</composite:implementation>
The core JSF implementation will nicely fire the Ajax events and do the Partial Page Rendering, part of which is the render of an <h:messages>
that confirms the event was processed successfully.
核心 JSF 实现将很好地触发 Ajax 事件并执行部分页面渲染,其中一部分是<h:messages>
确认事件已成功处理的渲染。
When I replace the <h:dataTable>
with a <p:dataTable>
, no problem. However, if I replace the <h:commandButton>
and <h:commandLink>
with <p:commandButton>
and <p:commandLink>
, the Ajax events are not making it to the <f:ajax>
Ajax Group element. The record delete and insert operations do actually happen on the server, but the page is never refreshed. I will appear to the user that nothing happened. If you click the browser Refresh button, you will see that the operation did indeed happen. If you click the core JSF command button or command link, everything works. The PrimesFaces table renders and even the PrimeFaces "growl" popups are displayed as expected.
当我<h:dataTable>
用 a替换时<p:dataTable>
,没问题。但是,如果我更换<h:commandButton>
,并<h:commandLink>
用<p:commandButton>
和<p:commandLink>
,阿贾克斯事件不能够进入<f:ajax>
阿贾克斯组元素。记录删除和插入操作确实发生在服务器上,但页面永远不会刷新。我会向用户显示什么都没有发生。如果单击浏览器刷新按钮,您将看到该操作确实发生了。如果单击核心 JSF 命令按钮或命令链接,则一切正常。PrimesFaces 表呈现,甚至 PrimeFaces “咆哮”弹出窗口也按预期显示。
Here is a screenshot of the PrimeFaces implementation that has the problem. Again, pardon the ugliness of the buttons and links.
这是有问题的 PrimeFaces 实现的屏幕截图。再次请原谅按钮和链接的丑陋。
First, the page:
一、页面:
<p:growl id="growl" showSummary="false" showDetail="true" />
<h:form id="dataTableForm" styleClass="ui-widget">
<f:ajax
listener="#{dataTableTestBean.processAjaxBehavior}"
event="action"
render="@form :growl :ajaxRenderTargetsInTemplate">
<h:panelGroup id="dataTablePanelGroup">
<p:commandLink
id="pfCommandLinkAddRow"
value="Add Sample Row (pf)"
ajax="true"
actionListener="#{dataTableTestBean.handleAddDataTableRow}" />
<p:commandButton
id="pfCommandButtonAddRow"
value="Add Sample Row (pf)"
ajax="true"
actionListener="#{dataTableTestBean.handleAddDataTableRow}" />
<h:commandLink
id="hCommandLinkAddRow"
value="Add Sample Row (h)"
actionListener="#{dataTableTestBean.handleAddDataTableRow}" />
<h:commandButton
id="hCommandButtonAddRow"
value="Add Sample Row (h)"
actionListener="#{dataTableTestBean.handleAddDataTableRow}" />
<sandbox:primeFacesDataTableCC
id="dataTableCC"
valueList="#{dataTableTestBean.dataTableList}" />
</h:panelGroup>
</f:ajax>
<h:panelGroup rendered="#{empty dataTableTestBean.dataTableList}">
<h3>No Records To Display</h3>
</h:panelGroup>
<h:commandButton
id="commandButtonBackToStartPage"
value="#{bundle.backToStartPage}"
action="start"
immediate="true" />
</h:form>
and the CC:
和 CC:
<composite:implementation>
<p:dataTable
id="theDataTable"
rendered="#{not empty cc.attrs.valueList}"
value="#{cc.attrs.valueList}"
var="row"
emptyMessage="#{bundle.dataTableEmptyMessage}">
<f:facet name="header">#{bundle.dataTableHeader}</f:facet>
<p:column id="columnpclDelete">
<p:commandLink
id="pclDelete"
value="Delete (pf)"
action="#{dataTableTestBean.actionDeleteDataTableRow(row)}" />
</p:column>
<p:column id="columnpcbDeleteIconOnly">
<p:commandButton
id="pcbDeleteIconOnly"
ajax="true"
global="true"
alt="#{bundle.delete}"
image="ui-icon ui-icon-trash"
action="#{dataTableTestBean.actionDeleteDataTableRow(row)}" />
</p:column>
<p:column id="columnhclDelete">
<h:commandLink
id="hclDelete"
value="Delete (h)"
action="#{dataTableTestBean.actionDeleteDataTableRow(row)}" />
</p:column>
<p:column id="columnhcbDeleteWithImage">
<h:commandButton
id="hcbDeleteWithImage"
alt="#{bundle.delete}"
image="#{resource['images/onebit_33_24x24.gif']}"
action="#{dataTableTestBean.actionDeleteDataTableRow(row)}" />
</p:column>
<p:column id="columnName" sortBy="#{row.name}">
<f:facet name="header">
#{bundle.columnHeaderName}
</f:facet>
<h:outputText value="#{row.name}" />
</p:column>
<p:column id="columnRank" sortBy="#{row.rank}">
<f:facet name="header">
#{bundle.columnHeaderRank}
</f:facet>
<h:outputText value="#{row.rank}" />
<f:facet name="footer">
#{bundle.columnFooterRank}
</f:facet>
</p:column>
<p:column id="serialNumber" sortBy="#{row.serialNumber}">
<f:facet name="header">
#{bundle.columnHeaderSerialNumber}
</f:facet>
<h:outputText value="#{row.serialNumber}" />
<f:facet name="footer">
#{bundle.columnFooterSerialNumber}
</f:facet>
</p:column>
<f:facet name="footer">#{bundle.dataTableFooter}</f:facet>
</p:dataTable>
</composite:implementation>
Where have I gone wrong? Everything works correctly except for the Ajax events from the PrimeFaces components.
我哪里错了?除了来自 PrimeFaces 组件的 Ajax 事件外,一切正常。
回答by Jim Tough
So apparently the PrimeFaces <p:commandButton>
and <p:commandLink>
tags cannot be used interchangeably with <h:commandButton>
and <h:commandLink>
. I thought they supported the base behavior of the core JSF tags and then provided more PrimeFaces-specific stuff in addition to that. This is not the case. The PrimeFaces tags are different and only provide some of the behavior of the core JSF tags of the same name.
所以显然 PrimeFaces<p:commandButton>
和<p:commandLink>
标签不能与<h:commandButton>
和互换使用<h:commandLink>
。我认为他们支持核心 JSF 标签的基本行为,然后除此之外还提供了更多 PrimeFaces 特定的东西。不是这种情况。PrimeFaces 标签不同,仅提供同名核心 JSF 标签的部分行为。
So the solution to my problem is not really ideal. The PrimeFaces tags will not participate in an Ajax group using <f:ajax>
to enclose a group of controls (as you can do with the core JSF tags). Also, the PrimeFaces command button and command link will not use a <f:ajax>
or <p:ajax>
child. There are two attributes that it will look for to enable Ajax behavior: 'update' and 'ajax'.
所以我的问题的解决方案并不是很理想。PrimeFaces 标签不会参与 Ajax 组,<f:ajax>
用于包含一组控件(就像使用核心 JSF 标签一样)。此外,PrimeFaces 命令按钮和命令链接不会使用 a<f:ajax>
或<p:ajax>
child。它将寻找两个属性来启用 Ajax 行为:'update' 和 'ajax'。
Each tag must have an 'update' attribute that contains a space-separated list of Ajax render targets, just like the 'render' attribute of <f:ajax>
. My PrimeFaces components are inside a Composite Component, so I have had to pass the list of render targets via a CC interface attribute.
每个标签都必须有一个 'update' 属性,其中包含一个空格分隔的 Ajax 渲染目标列表,就像<f:ajax>
. 我的 PrimeFaces 组件位于复合组件内,因此我不得不通过 CC 接口属性传递渲染目标列表。
My command button inside the CC looks like this now:
我在 CC 中的命令按钮现在看起来像这样:
<p:commandButton
id="pCommandButtonDeleteIconOnly"
alt="#{bundle.delete}"
image="ui-icon ui-icon-trash"
ajax="true"
update="#{cc.attrs.ajaxRenderTargets}"
action="#{dataTableTestBean.actionDeleteDataTableRow(row)}" />
If I didn't want the command button to execute as an Ajax call, then apparently the 'ajax' attribute should be set to "false" and the 'update' attribute should not be provided at all. This SO questionhelped point me in the right direction.
如果我不希望命令按钮作为 Ajax 调用执行,那么显然 'ajax' 属性应该设置为“false”并且根本不应该提供 'update' 属性。这个问题帮助我指明了正确的方向。
回答by maple_shaft
There are strange issues that can crop up if you are using an <f:ajax>
tag for Primefaces components.
如果您<f:ajax>
为 Primefaces 组件使用标签,可能会出现一些奇怪的问题。
Try utilizing the Primefaces ajax tag, <p:ajax>
尝试使用 Primefaces ajax 标签, <p:ajax>
EDIT: I just want to point out that you mayrun into an issue with an ajax refresh of a <p:dataTable>
from a component withinthat dataTable. This bug existed as of Primefaces 2.2.1 however it maybe fixed in 3.0.
编辑:我只是想指出的是,你可能遇到的问题与的一个ajax刷新<p:dataTable>
从组件内该数据表。这个错误在 Primefaces 2.2.1 中存在,但它可能会在 3.0 中修复。