jsf remotecommand - 了解PrimeFaces進程/更新和JSF f:ajax執行/渲染屬性




2 Answers

<p:commandXxx process> <p:ajax process> <f:ajax execute>

process屬性是服務器端,只能影響實現EditableValueHolder (輸入字段)或ActionSource (命令字段)的UIComponentprocess屬性告訴JSF,使用空格分隔的客戶端ID列表,在(部分)表單提交時,完全必須通過整個JSF生命週期處理哪些組件。

然後,JSF將應用請求值(根據組件自己的客戶端ID查找HTTP請求參數,然後在EditableValueHolder組件的情況下將其設置為提交的值,或者在ActionSource組件的情況下排隊新的ActionEvent ),執行轉換,驗證和更新模型值(僅限EditableValueHolder組件),最後調用排隊的ActionEventActionSource組件)。 JSF將跳過對process屬性未涉及的所有其他組件的process 。 此外,在應用請求值階段期間rendered屬性評估為false組件也將被跳過作為防範篡改請求的一部分。

請注意,在ActionSource組件(如<p:commandButton> )的情況下非常重要,因為您還可以將組件本身包含在process屬性中,特別是如果您打算調用與該組件相關聯的操作。 所以下面這個例子,當某個命令組件被調用時,它只打算處理某些輸入組件,但這樣做不會奏效:

<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="foo" action="#{bean.action}" />

它只會處理#{bean.foo}不是 #{bean.action} 。 你還需要包含命令組件本身:

<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@this foo" action="#{bean.action}" />

或者,正如您明顯發現的那樣,如果它們碰巧是具有共同父項的唯一組件,則使用@parent

<p:panel><!-- Type doesn't matter, as long as it's a common parent. -->
    <p:inputText id="foo" value="#{bean.foo}" />
    <p:commandButton process="@parent" action="#{bean.action}" />
</p:panel>

或者,如果它們碰巧是父UIForm組件的唯一組件,那麼您也可以使用@form

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" />
    <p:commandButton process="@form" action="#{bean.action}" />
</h:form>

如果表單包含更多想要在處理中跳過的輸入組件,這通常是不理想的,而當您想要更新其他輸入組件或基於當前輸入組件的某個UI部分時,一個ajax監聽器方法。 您不希望其他輸入組件上的驗證錯誤阻止執行ajax偵聽器方法。

然後是@all 。 這在process屬性中沒有特殊效果,但僅在update屬性中有效。 process="@all"行為與process="@form"行為完全相同。 HTML不支持一次提交多個表單。

還有一種@none ,它可以用於萬一你不需要處理任何東西,但只想通過update更新某些特定部分,特別是那些內容不依賴於提交的值或動作偵聽器的部分。

與PrimeFaces特定process等效的標準JSF是從<f:ajax execute> 。 它的行為完全一樣,只不過它不支持逗號分隔的字符串,而PrimeFaces卻不支持(儘管我個人建議只堅持空格分隔的約定),也不支持@parent關鍵字。 另外,知道<p:commandXxx process>默認為@form<p:ajax process><f:ajax execute>默認為@this可能會很有用。 最後,了解該process支持所謂的“PrimeFaces選擇器”也很有用,另請參閱PrimeFaces選擇器如update =“@(。myClass)”的工作方式?

<p:commandXxx update> <p:ajax update> <f:ajax render>

update屬性是客戶端,可以影響所有UIComponent的HTML表示。 update屬性告訴JavaScript(負責處理ajax請求/響應的那個),使用空格分隔的客戶端ID列表,HTML格式樹中的哪些部分需要更新,以響應表單提交。

然後,JSF將為此準備正確的ajax響應, 包含要更新的請求部分。 JSF將跳過ajax響應中沒有被update屬性覆蓋的所有其他組件,因此保持響應有效負載很小。 此外,在呈現響應階段rendered屬性評估為false組件將被跳過。 請注意,即使它返回true ,JavaScript也無法在HTML DOM樹中更新它,如果它最初是false 。 您需要將其包裝或更新其父項。 另請參見Ajax更新/渲染不適用於已呈現屬性的組件

通常情況下,您只想更新(部分)表單提交時真正需要在客戶端“刷新”的組件。 下面的示例通過@form更新整個父窗體:

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" required="true" />
    <p:message id="foo_m" for="foo" />
    <p:inputText id="bar" value="#{bean.bar}" required="true" />
    <p:message id="bar_m" for="bar" />
    <p:commandButton action="#{bean.action}" update="@form" />
</h:form>

(請注意, process屬性被省略,因為它已經默認為@form

雖然這可能工作得很好,但輸入和命令組件的更新在這個特例中是不必要的。 除非你在action方法中改變模型值foobar (這在UX視角中反過來是不直觀的),否則沒有必要更新它們。 消息組件是唯一真正需要更新的組件:

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" required="true" />
    <p:message id="foo_m" for="foo" />
    <p:inputText id="bar" value="#{bean.bar}" required="true" />
    <p:message id="bar_m" for="bar" />
    <p:commandButton action="#{bean.action}" update="foo_m bar_m" />
</h:form>

然而,當你有很多這些時,這會變得乏味。 這是PrimeFaces選擇器存在的原因之一。 這些消息組件在生成的HTML輸出中具有通用樣式類的ui-message ,因此以下內容也應該這樣做:

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" required="true" />
    <p:message id="foo_m" for="foo" />
    <p:inputText id="bar" value="#{bean.bar}" required="true" />
    <p:message id="bar_m" for="bar" />
    <p:commandButton action="#{bean.action}" update="@(.ui-message)" />
</h:form>

(請注意,您應該在消息組件上保留ID,否則@(...)將不起作用!請再次參閱update =“@(。myClass)”中的PrimeFaces選擇器如何工作以獲取詳細信息)

@parent只更新父組件,它涵蓋了當前組件以及所有兄弟姐妹及其子組件。 如果你將表格分成了自己的團隊和每個人自己的責任,這會更有用。 @this顯然只更新當前組件。 通常,只有當您需要在操作方法中更改某個組件自己的HTML屬性時才需要。 例如

<p:commandButton action="#{bean.action}" update="@this" 
    oncomplete="doSomething('#{bean.value}')" />

想像一下,不完整的需要使用在action更改的value ,那麼如果組件未更新,此構造將無法工作,原因很簡單,因為oncomplete是生成的HTML輸出的一部分(因此所有EL表達式在渲染響應期間評估)。

@all更新整個文檔,應謹慎使用。 通常情況下,您希望對此使用真正的GET請求,而不是通過簡單鏈接( <a><h:link> )或者通過?faces-redirect=trueExternalContext#redirect()後的POST ExternalContext#redirect() 。 在效果中, process="@form" update="@all"與非ajax(非部分)提交具有完全相同的效果。 在我的整個JSF職業生涯中,我遇到的@all唯一合理的用例是在ajax請求發生異常的情況下全部顯示錯誤頁面。 另請參見處理AJAX化組件的JSF 2.0異常的正確方法是什麼?

與PrimeFaces特定update等效的標準JSF是從<f:ajax render> 。 它的行為完全一樣,只不過它不支持逗號分隔的字符串,而PrimeFaces卻不支持(儘管我個人建議只堅持空格分隔的約定),也不支持@parent關鍵字。 updaterender默認為@none (即“沒有”)。

也可以看看:

text @previous

PrimeFaces p:commandXxx組件中的processupdate以及f:ajax標記中的executerender到底是什麼?

哪些在驗證時有效? update屬性的作用是什麼,而不是從後端更新組件值? 是否將屬性綁定值處理為模型? @form @parent@form @parent@form @parent@parent在兩個屬性中究竟做了什麼?

下面的例子工作正常,但我對基本概念有點困惑。

<p:commandButton process="@parent"
                 update="@form"
                 action="#{bean.submit}" 
                 value="Submit" />



按照流程(在JSF規範中稱為execute),您告訴JSF將處理限制為只是被忽略的其他指定的組件。

更新指示服務器回應您的請求時將更新哪個元素。

@all :處理/呈現每個組件。

@this :處理/呈現具有execute屬性的請求組件。

@form :處理/呈現包含請求組件的表單。

@parent :處理/呈現包含請求組件的父代。

有了Primefaces,你甚至可以使用JQuery選擇器,看看這個博客: http://blog.primefaces.org/?p=1867 ://blog.primefaces.org/?p=1867




Related