PrimeFacesプロセス/更新とJSF f:ajax実行/レンダリング属性を理解する


193

正確に何であるprocessupdatePrimeFacesの中でp:commandXxxコンポーネントとexecuterenderf:ajaxタグ?

検証時にどちらが機能しますか?updateバックエンドからコンポーネントの値を更新するのではなく、属性は何をしますか?やるprocessモデルに属性のバインド値を?正確に何を@this@parent@all@form両方の属性に?

以下の例は問題なく機能していますが、基本的な概念について少し混乱しています。

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

回答:


306

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

process属性は、サーバー側でのみ影響を与える可能性がUIComponent実装S EditableValueHolder(入力フィールド)またはActionSource(コマンドフィールド)。このprocess属性は、スペースで区切られたクライアントIDのリストを使用して、JSFに、(部分的な)フォームの送信時にJSFライフサイクル全体で正確に処理する必要があるコンポーネントを通知します。

JSFは、(コンポーネントの独自のクライアントIDに基づいてHTTPリクエストパラメータを検索し、次にいずれかの場合に送信された値として設定する要求値を適用するEditableValueHolderコンポーネントまたは新しいキューイングActionEventの場合ActionSource(検証、変換を実行し、コンポーネント)とモデル値を更新しますEditableValueHolderコンポーネントのみ)、最後にキューに入れられたコンポーネントActionEventActionSourceコンポーネントのみ)を呼び出します。JSFは、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絶対に何も処理する必要はないが、特に、送信された値やアクションリスナーに依存しないコンテンツを持つセクションを介して、特定の部分のみを更新したい場合に役立つa もありますupdate

このprocess属性はHTTPリクエストのペイロード(リクエストパラメータの量)に影響を与えないことに注意してください。つまり、のHTML表現に含まれる「すべて」を送信するデフォルトのHTML動作には<h:form>影響しません。ケースでは、大規模なフォームを持っている、とIEのみこれらはによってカバーされ、処理にのみこれらの絶対に必要にHTTPリクエストのペイロードを減らしたいprocess、属性その後、あなたが設定できるpartialSubmitのようにPrimeFaces Ajaxコンポーネント内の属性を<p:commandXxx ... partialSubmit="true"><p:ajax ... partialSubmit="true">。編集web.xmlして追加することで、この「グローバル」を構成することもできます

<context-param>
    <param-name>primefaces.SUBMIT</param-name>
    <param-value>partial</param-value>
</context-param>

あるいは、<o:form>デフォルトでこの動作になるOmniFaces 3.0以降を使用することもできます。

PrimeFaces固有の標準JSF processexecuteから<f:ajax execute>です。PrimeFacesがサポートする一方でコンマで区切られた文字列をサポートしないことを除いて、まったく同じように動作します(ただし、個人的にはスペースで区切られた規則に従うことをお勧めします)@parent。また、<p:commandXxx process>デフォルトが@formwhileで<p:ajax process><f:ajax execute>デフォルトがであることを知っておくと便利です@this。最後に、processいわゆる "PrimeFaces Selectors" をサポートするを知っていることも役立ちます。また、「update = "@(。myClass)"のようにPrimeFaces Selectorsがどのように機能するか」も参照してください。


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

update属性は、クライアント側であり、すべてのHTML表現に影響することができますUIComponent秒。このupdate属性は、スペースIDで区切られたクライアントIDのリストを使用して、JavaScript(ajax要求/応答の処理を担当するもの)に、フォーム送信への応答としてHTML DOMツリーのどの部分を更新する必要があるかを伝えます。

次に、JSFはそのための適切なajax応答を準備します。これには、更新が要求された部分のみが含まれます。JSFはupdate、ajax応答の属性でカバーされていない他のすべてのコンポーネントをスキップして、応答ペイロードを小さく保ちます。また、応答のレンダリング段階でrendered属性が評価されるコンポーネントfalseはスキップされます。trueJavaScript は戻りますが、最初の場合は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すでに省略されているため、省略されていることに注意してください)

これは問題なく動作する可能性がありますが、この特定の例では入力コンポーネントとコマンドコンポーネントの更新は不要です。モデル値foobar内部actionメソッドを変更しない限り(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 Selectorsが存在する理由の1つです。これらのメッセージコンポーネントは、生成された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属性の1つを変更する必要がある場合のみです。例えば

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

で変更されたを処理するoncomplete必要があると想像してください。生成されたHTML出力の一部である単純な理由により、コンポーネントが更新されない場合、この構成は機能しません(したがって、そこにあるすべてのEL式が評価されます)レンダリング応答時)。valueactiononcomplete

@allドキュメント全体を更新するため、注意して使用する必要があります。通常は、あなたの代わりに、プレーンリンク(いずれかの方法で、このための真のGETリクエストを使用したい<a><h:link>)またはによってリダイレクト後-POST ?faces-redirect=trueまたはExternalContext#redirect()。効果では、process="@form" update="@all"正確に非アヤックス(非部分)を提出するのと同じ効果があります。私のJSFのキャリア全体で、私が遭遇した唯一の賢明なユースケース@allは、ajaxリクエスト中に例外が発生した場合にエラーページ全体を表示することです。参照AJAX化されたコンポーネントのJSF 2.0例外を処理する正しい方法は何ですか?

PrimeFaces固有の標準JSF updaterenderから<f:ajax render>です。PrimeFacesがサポートする一方でコンマで区切られた文字列をサポートしないことを除いて、まったく同じように動作します(ただし、個人的にはスペースで区切られた規則に従うことをお勧めします)@parent。どちらupdaterenderデフォルトに@none(これは、「何もありません」)。


以下も参照してください。


update = ""を使用すると、バッキングBeanの管理プロパティが設定されず、@ PostConstructルーチンが失敗します。何かご意見は?編集:•#{param}の管理プロパティが後続のPOSTリクエストに存在することに依存している場合は、UICommandコンポーネントに<f:param>として含める必要があります。
K.Nicholas 14

panelGroupの処理/更新により、このpanelGroupの内容が処理/更新される場合がありますex:<h:panelGroup id = "pgId"> // input texts Go here <h:panelGroup> <p:commandLink process = "pgId" update = "pgId" />
bob-cac

@xBalusCにこの非常に素晴らしい説明を書いてください。
ProgrammingIsAwsome

2
@Rapster:processが設定されていないため、デフォルト値のを使用します@form。これは上記の回答でも説明されています。
BalusC 2016年

2
@Roland:それは、アプリ構成に関する別の、より深刻な、問題を隠しています。
BalusC 2018年

54

デフォルト値を覚えるのに苦労している場合(私は知っています...)は、BalusCの答えからの短い抜粋です。

コンポーネント| 送信| リフレッシュ
------------ | --------------- | --------------
f:ajax | execute = "@ this" | render = "@ none"
p:ajax | process = "@ this" | update = "@ none"
p:commandXXX | process = "@ form" | update = "@ none"

ほんの小さな修正:processfor のデフォルト値はp:commandXXXです@all。さらに、これはなどのAJAXをサポートするすべてのコンポーネントに適用されるようp:menuitemです。
ステファンラウ2016年

1
こんにちは@StephanRauh、コメントありがとうございます。デフォルトはどこで読みました@allか?私がBalusCの答えから読むことができる限り、それはですが@form、進行中@allと同等@formです。他のコンポーネントについての良い点は、私はむしろ、書き込みではない何かが間違っている可能性がありますそのような時間は、それが適用されるものをコンポーネント参照してくださいときに、ソースコードで見ているだろうと思います
Jaqen H'ghar

1
@ JaqenH'ghar Thomas Andraschkoが@all少し話してくれました。彼は知っておく必要があります、彼は最近PrimeFacesのAJAXエンジンを再実装しました。後で、私はそれを再確認しましたが、PrimeFacesのソースコードを読み、XHRリクエストを確認しました。PrimeFacesのAJAXリクエストと同じように機能するようにBootsFacesのAJAXリクエストを実装したので、今回はうまくいけばいいのですが。
ステファンラウ2016年

HTMLが複数のフォームの送信をサポートしていない場合、デフォルトは@allであると言うのは誤解を招くでしょう。開発者は有効なデフォルト値を知る必要があります(そのため、Thomasはそれに応じて変更する可能性があります)。ちなみに、これらのデフォルトは、Primefacesユーザーガイド6.2で誤ってnullとして定義されています。
Marc Dzaebel 2018年

27

プロセスによって(JSF仕様では実行と呼ばれます)、JSFに処理をコンポーネントに限定するように指示します。

updateは、サーバーがリクエストに応答したときに更新される要素を示します。

@all:すべてのコンポーネントが処理またはレンダリングされます。

@this:execute属性を持つ要求コンポーネントが処理またはレンダリングされます。

@form:リクエストするコンポーネントを含むフォームが処理またはレンダリングされます。

@parent:リクエストコンポーネントを含む親が処理またはレンダリングされます。

Primefacesであなたも、jQueryのセレクタを使用して、このブログをチェックアウトすることができますhttp://blog.primefaces.org/?p=1867を


2

PrimeFacesは標準のJSF 2.0+キーワードをサポートしていることに注意してください。

  • @this 現在のコンポーネント。
  • @all 全景。
  • @form 現在のコンポーネントの最も近い祖先形式。
  • @none コンポーネントはありません。

および標準のJSF 2.3以降のキーワード:

  • @child(n) n番目の子。
  • @composite 最も近い複合コンポーネントの祖先。
  • @id(id) コンポーネントツリー構造と名前付けコンテナーを無視して、IDでコンポーネントを検索するために使用されます。
  • @namingcontainer 現在のコンポーネントの最も近い祖先命名コンテナ。
  • @parent 現在のコンポーネントの親。
  • @previous 前の兄弟。
  • @next 次の兄弟。
  • @root ビューのUIViewRootインスタンス。現在のコンポーネントの代わりにルートから検索を開始するために使用できます。

ただし、PrimeFaces固有のキーワードもいくつか含まれています。

  • @row(n) n行目。
  • @widgetVar(name) 指定されたwidgetVarを持つコンポーネント。

また、jQuery Selector APIを使用できる「PrimeFaces Selectors」と呼ばれるものを使用することもできます。たとえば、CSSクラスを持つ要素のすべての入力を処理するには、次のようにしますmyClass

process="@(.myClass :input)"

見る:


2
JSF2.3 +でさえ、ほとんどのキーワードをサポートしています。
tandraschko
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.