簡體   English   中英

PrimeFaces 3.0 - f:ajax Ajax 組未從 p:commandButton 或 p:commandLink 接收事件

[英]PrimeFaces 3.0 - f:ajax Ajax Group not receiving events from p:commandButton or p:commandLink

我正在嘗試將 PrimeFaces 3.0 集成到我的 JSF 2.0 項目中。 我創建了一些示例代碼來嘗試獲取 PrimeFaces <p:dataTable>在每一行的列中都有一個刪除按鈕/鏈接。 我希望刪除操作觸發表的 Ajax 刷新(我當前的代碼使用@form 觸發封閉表單的呈現)。

我的問題是 PrimeFaces 組件似乎沒有觸發可以由核心 JSF <f:ajax>標簽處理的事件。 我將<f:ajax>用作包含<p:dataTable>以及另一個命令按鈕的 Ajax 組。

如果我純粹使用核心 JSF 元素( <h:dataTable><h:commandButton>等)實現這一點,那么一切都會按預期工作。 請原諒丑陋的 output,但我不會在示例代碼的 CSS 樣式上浪費時間。

丑陋但功能正常的核心 JSF 實現

以下是核心 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>

以下是核心 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>

核心 JSF 實現將很好地觸發 Ajax 事件並進行部分頁面渲染,其中一部分是確認事件已成功處理的<h:messages>的渲染。

當我用<p:dataTable>替換<h:dataTable> > 時,沒問題。 但是,如果我將<h:commandButton><h:commandLink>替換為<p:commandButton><p:commandLink> ,則 Ajax 事件不會進入<f:ajax> Ajax 組元素。 記錄刪除和插入操作確實發生在服務器上,但頁面永遠不會刷新。 我會向用戶顯示什么都沒有發生。 如果單擊瀏覽器的刷新按鈕,您將看到該操作確實發生了。 如果單擊核心 JSF 命令按鈕或命令鏈接,一切正常。 PrimesFaces 表呈現,甚至 PrimeFaces“咆哮”彈出窗口都按預期顯示。

這是出現問題的 PrimeFaces 實現的屏幕截圖。 同樣,請原諒按鈕和鏈接的丑陋。

有 Ajax 事件問題的 PrimeFaces 實現

一、頁面:

<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>

和抄送:

<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>

我哪里出錯了? 除了來自 PrimeFaces 組件的 Ajax 事件外,一切正常。

所以顯然 PrimeFaces <p:commandButton><p:commandLink>標簽不能與<h:commandButton><h:commandLink>互換使用。 我認為他們支持核心 JSF 標簽的基本行為,然后除此之外還提供了更多 PrimeFaces 特定的東西。 不是這種情況。 PrimeFaces 標簽不同,僅提供同名的核心 JSF 標簽的一些行為。

所以我的問題的解決方案並不是很理想。 PrimeFaces 標簽將不參與使用<f:ajax>封裝一組控件的 Ajax 組(就像您可以使用核心 JSF 標簽一樣)。 此外,PrimeFaces 命令按鈕和命令鏈接不會使用<f:ajax><p:ajax>子項。 它將尋找兩個屬性來啟用 Ajax 行為:“更新”和“ajax”。

每個標簽都必須有一個“更新”屬性,其中包含一個以空格分隔的 Ajax 渲染目標列表,就像<f:ajax>的“渲染”屬性一樣。 我的 PrimeFaces 組件位於復合組件內,因此我必須通過 CC 接口屬性傳遞渲染目標列表。

我在 CC 中的命令按鈕現在看起來像這樣:

<p:commandButton
    id="pCommandButtonDeleteIconOnly"
    alt="#{bundle.delete}"
    image="ui-icon ui-icon-trash"
    ajax="true"
    update="#{cc.attrs.ajaxRenderTargets}"
    action="#{dataTableTestBean.actionDeleteDataTableRow(row)}" />

如果我不希望命令按鈕作為 Ajax 調用執行,那么顯然應該將“ajax”屬性設置為“false”並且根本不應該提供“update”屬性。 這個SO question幫助我指出了正確的方向。

如果您對 Primefaces 組件使用<f:ajax>標記,可能會出現一些奇怪的問題。

嘗試使用 Primefaces ajax 標簽, <p:ajax>

編輯:我只想指出,您可能會遇到從該數據表的組件刷新<p:dataTable>的 ajax 的問題。 此錯誤自 Primefaces 2.2.1 起就存在,但它可能會在 3.0 中修復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM