HTML出力で実際のクライアントIDを確認します
適切なクライアントIDを見つけるには、生成されたHTML出力を調べる必要があります。ブラウザでページを開き、右クリックしてソースを表示します。対象のJSFコンポーネントのHTML表現を見つけ、それid
をクライアントIDとして取得します。現在の命名コンテナに応じて、絶対的または相対的な方法で使用できます。次の章を参照してください。
注:それはのような反復指数含まれて発生した場合:0:
、:1:
などを、(それが反復コンポーネント内だから)、あなたは、特定の反復ラウンドの更新は常にサポートされていないことを認識する必要があります。詳細については、回答の下部を参照してください。
NamingContainer
コンポーネントを記憶し、常に固定IDを与える
ajax process / execute / update / renderで参照するコンポーネントが同じNamingContainer
親の中にある場合は、そのコンポーネントのIDを参照するだけです。
<h:form id="form">
<p:commandLink update="result"> <!-- OK! -->
<h:panelGroup id="result" />
</h:form>
同じ内にない場合はNamingContainer
、絶対クライアントIDを使用して参照する必要があります。絶対クライアントIDは、NamingContainer
区切り文字(デフォルトでは)で始まります:
。
<h:form id="form">
<p:commandLink update="result"> <!-- FAIL! -->
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
<p:commandLink update=":result"> <!-- OK! -->
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
<p:commandLink update=":result"> <!-- FAIL! -->
</h:form>
<h:form id="otherform">
<h:panelGroup id="result" />
</h:form>
<h:form id="form">
<p:commandLink update=":otherform:result"> <!-- OK! -->
</h:form>
<h:form id="otherform">
<h:panelGroup id="result" />
</h:form>
NamingContainer
コンポーネントは、例えばある<h:form>
、<h:dataTable>
、<p:tabView>
、<cc:implementation>
(したがって、すべての複合コンポーネント)などは、あなたが生成されたHTML出力を見て、簡単にそれらを認識し、そのIDは、すべての子コンポーネントの生成されたクライアントIDの先頭に追加されます。固定IDがない場合、JSFは自動生成されたIDをj_idXXX
フォーマットで使用することに注意してください。固定IDを与えることで、絶対にそれを回避する必要があります。OmniFacesは、NoAutoGeneratedIdViewHandler
開発中に、この中に有用であろう。
UIComponent
問題のJavadocを見つけることがわかっている場合は、NamingContainer
インターフェースが実装されているかどうかをチェックインすることもできます。たとえば、HtmlForm
(UIComponent
後ろの<h:form>
タグ)はそれを実装していることを示していますNamingContainer
が、HtmlPanelGroup
(UIComponent
後ろの<h:panelGroup>
タグ)はそれを示していないため、実装していませんNamingContainer
。ここでは、すべての標準コンポーネントのJavadocがあると、ここでPrimeFacesのjavadocのです。
問題を解決する
だからあなたの場合:
<p:tabView id="tabs"><!-- This is a NamingContainer -->
<p:tab id="search"><!-- This is NOT a NamingContainer -->
<h:form id="insTable"><!-- This is a NamingContainer -->
<p:dialog id="dlg"><!-- This is NOT a NamingContainer -->
<h:panelGrid id="display">
の生成されたHTML出力は<h:panelGrid id="display">
次のようになります。
<table id="tabs:insTable:display">
それid
をクライアントIDとして正確に受け取り、次に:
使用するためにプレフィックスを付ける必要がありますupdate
。
<p:commandLink update=":tabs:insTable:display">
include / tagfile / composite外での参照
このコマンドリンクがinclude / tagfile内にあり、ターゲットがその外にあるため、現在の名前付けコンテナーの親である名前付けコンテナーのIDが必ずしもわからない場合は、次のUIComponent#getNamingContainer()
ようにして動的に参照できます。
<p:commandLink update=":#{component.namingContainer.parent.namingContainer.clientId}:display">
または、このコマンドリンクが複合コンポーネント内にあり、ターゲットがその外にある場合:
<p:commandLink update=":#{cc.parent.namingContainer.clientId}:display">
または、コマンドリンクとターゲットの両方が同じ複合コンポーネント内にある場合:
<p:commandLink update=":#{cc.clientId}:display">
render / update属性については、テンプレートの親ネーミングコンテナのIDを取得するもご覧ください。
カバーの下でどのように機能するか
これは、すべてのように指定された「検索式」でのJavadoc:UIComponent#findComponent()
検索式は、のidプロパティに対して正確に一致している識別子(いずれかで構成されUIComponent
、またはによって連結され、そのような識別子の一連のUINamingContainer#getSeparatorChar
文字値。以下のように代替alogrithmsが長いほど使用されてもよい探索アルゴリズムは、動作しなければなりません最終結果は同じです:
UIComponent
次のいずれかの条件が満たされるとすぐに停止して、検索のベースとなるを特定します。
- 検索式が区切り文字で始まる場合(「絶対」検索式と呼ばれます)、ベースは
UIComponent
コンポーネントツリーのルートになります。先頭の区切り文字は削除され、検索式の残りの部分は、以下で説明する「相対」検索式として扱われます。
- それ以外の場合、これ
UIComponent
がaの場合、NamingContainer
それが基礎となります。
- それ以外の場合は、このコンポーネントの親を検索します。に
NamingContainer
遭遇した場合、それがベースになります。
- それ以外の場合(
NamingContainer
遭遇しない場合)、ルートUIComponent
がベースになります。
- 検索式(前のステップで変更された可能性があります)は、「相対」検索式になり、ベースコンポーネントのスコープ内で、一致するIDを持つコンポーネント(存在する場合)を検索するために使用されます。照合は次のように実行されます。
- 検索式が単純な識別子の場合、この値はidプロパティと比較され、ベースのファセットと子を再帰的に再帰します
UIComponent
(子孫NamingContainer
が見つかった場合、その子孫と子は検索されません)。
- 検索式に、区切り文字で区切られた複数の識別子が含まれている場合、最初の識別子を使用して
NamingContainer
、前の箇条書きのルールでを検索します。次に、このfindComponent()
メソッドNamingContainer
が呼び出され、検索式の残りの部分が渡されます。
PrimeFacesもJSF仕様に準拠していますが、RichFacesは「いくつかの追加の例外」を使用しています。
「reRender」は、UIComponent.findComponent()
アルゴリズムを使用して(いくつかの追加の例外はあります)、コンポーネントツリーでコンポーネントを見つけます。
これらの追加の例外はどこにも詳しく説明されていませんが、相対コンポーネントID(つまり、で始まらないもの:
)は、最も近いparentのコンテキストで検索されるだけでなく、同じビュー内のNamingContainer
他のすべてのNamingContainer
コンポーネント(比較的ちなみに高価な仕事)。
使用しない prependId="false"
それでも問題が解決しない場合は、を使用していないかどうかを確認してください<h:form prependId="false">
。これは、ajax送信およびレンダリングの処理中に失敗します。この関連質問もご覧ください:prependId = "false"のあるUIFormが<f:ajax render>を壊します。
反復コンポーネントの特定の反復ラウンドの参照
長い間<ui:repeat>
、次の<h:dataTable>
ようなコンポーネントの反復で特定の反復アイテムを参照することはできませんでした。
<h:form id="form">
<ui:repeat id="list" value="#{['one','two','three']}" var="item">
<h:outputText id="item" value="#{item}" /><br/>
</ui:repeat>
<h:commandButton value="Update second item">
<f:ajax render=":form:list:1:item" />
</h:commandButton>
</h:form>
ただし、Mojarra 2.2.5以降は<f:ajax>
サポートを開始しました(検証を停止しただけなので、上記の質問の例外に直面することはもうありません。別の拡張機能の修正が後で計画されています)。
これは、現在のMyFaces 2.2.7およびPrimeFaces 5.2バージョンではまだ機能しません。サポートは将来のバージョンで提供される可能性があります。その間、あなたの最善の策は、反復コンポーネント自体、またはのようにHTMLをレンダリングしない場合は親を更新することです<ui:repeat>
。
PrimeFacesを使用する場合は、検索式またはセレクターを検討してください
PrimeFaces検索式を使用すると、JSFコンポーネントツリー検索式を介してコンポーネントを参照できます。JSFにはいくつかの組み込み機能があります。
@this
:現在のコンポーネント
@form
:親 UIForm
@all
:ドキュメント全体
@none
:なし
PrimeFacesは、新しいキーワードと複合式のサポートによりこれを強化しました。
@parent
:親コンポーネント
@namingcontainer
:親 UINamingContainer
@widgetVar(name)
:指定されたコンポーネント widgetVar
また、のような複合式でそれらのキーワードを混在させることができ@form:@parent
、@this:@parent:@parent
など
PrimeFaces Selectors(PFS)では、@(.someclass)
jQuery CSSセレクター構文を介してコンポーネントを参照できます。たとえば、HTML出力にすべての共通のスタイルクラスを持つ参照コンポーネント。これは、「多くの」コンポーネントを参照する必要がある場合に特に役立ちます。これは、ターゲットコンポーネントにすべてのクライアントIDがHTML出力に含まれていることを前提としています(固定または自動生成のどちらでも構いません)。「PrimeFaces Selectors as update = "@(。myClass)"はどのように機能するか」も参照してください。