[解決済み] ajax更新/レンダーのためのコンポーネントのクライアントIDを見つける方法?bar "から "foo "を参照する式でコンポーネントを見つけることができません。
質問
以下のコードは、PrimeFaces DataGrid + DataTable Tutorialsからインスピレーションを受け、PrimeFaces DataGrid + DataTable Tutorialsの中で
<p:tab>
の
<p:tabView>
に居住している。
<p:layoutUnit>
の
<p:layout>
. 以下は、コードの内側の部分です。
p:tab
コンポーネントで構成される)。外側の部分は些細なことである。
<p:tabView id="tabs">
<p:tab id="search" title="Search">
<h:form id="insTable">
<p:dataTable id="table" var="lndInstrument" value="#{instrumentBean.instruments}">
<p:column>
<p:commandLink id="select" update="insTable:display" oncomplete="dlg.show()">
<f:setPropertyActionListener value="#{lndInstrument}"
target="#{instrumentBean.selectedInstrument}" />
<h:outputText value="#{lndInstrument.name}" />
</p:commandLink>
</p:column>
</p:dataTable>
<p:dialog id="dlg" modal="true" widgetVar="dlg">
<h:panelGrid id="display">
<h:outputText value="Name:" />
<h:outputText value="#{instrumentBean.selectedInstrument.name}" />
</h:panelGrid>
</p:dialog>
</h:form>
</p:tab>
</p:tabView>
をクリックすると
<p:commandLink>
が表示されると、コードは動作しなくなり
メッセージ
:
tabs:insTable:select" から参照される "insTable:display" 式を持つコンポーネントを見つけることができません。
を使用して同じことを試すと
<f:ajax>
で失敗し、別の
メッセージ
基本的に同じことを伝えています。
<f:ajax>
は、未知の ID "insTable:display" を含んでおり、コンポーネント "tabs:insTable:select" のコンテキスト内でそれを見つけることができません。
別のAjaxポストバック中に発生し、JSFプロジェクトステージが
Development
というJavaScriptのアラートが表示され、失敗します。
メッセージ
:
malformedXMLです。更新中:insTable:display が見つかりません。
この現象はどのように発生し、どのように解決すればよいのでしょうか?
どのように解決するのですか?
HTML出力で実際のクライアントIDを確認する
正しいクライアントIDを見つけるには、生成されたHTML出力を見る必要があります。ブラウザでページを開き、右クリックをして
ソースを見る
. 目的の JSF コンポーネントの HTML 表現を探し、その
id
をクライアントIDとして使用します。現在のネーミングコンテナに応じて、絶対的または相対的な方法で使用することができます。次の章を参照してください。
注意: もし、その中に
:0:
,
:1:
など(反復処理コンポーネント内にあるため)、特定の反復ラウンドの更新が常にサポートされているわけではないことを認識する必要があります。その詳細については、回答の最後を参照してください。
記憶する
NamingContainer
コンポーネントは常に固定されたIDを付与してください。
ajax処理/実行/更新/レンダリングで参照したいコンポーネントが同じ
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を与えることによって、絶対にそれを避けるべきです。その
オムニフェーズ
NoAutoGeneratedIdViewHandler
は、開発中にこれを参考にすることができるかもしれません。
のjavadocを見つけることが分かっている場合。
UIComponent
を実装しているかどうかを確認することができます。
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 を取得する。
裏側の仕組み
これはすべて
"検索式"
で
その
UIComponent#findComponent()
ジャバドック
:
A 検索式 は、識別子 (この識別子は、id プロパティと正確にマッチします。
UIComponent
によってリンクされた一連の識別子、またはUINamingContainer#getSeparatorChar
の文字値を指定します。検索アルゴリズムは以下の通りであるが、最終結果が同じであれば、他のアルゴリズムを用いてもよい。
- を識別します。
UIComponent
を、以下のいずれかの条件を満たした時点で停止し、検索のベースとする。
- 検索式が区切り文字で始まる場合("absolute"検索式と呼ばれる)、ベースはルート
UIComponent
コンポーネントツリーの 先頭のセパレータ文字は削除され、残りの検索式は以下のように"相対検索式として扱われます。- そうでない場合は、この
UIComponent
はNamingContainer
が基本になります。- そうでなければ、このコンポーネントの親を検索してください。もし
NamingContainer
に遭遇した場合、それがベースとなる。- それ以外(もし
NamingContainer
に遭遇した場合、ルートUIComponent
がベースとなります。- 検索式(前のステップで変更された可能性があります)は、ベースコンポーネントの範囲内で、一致するIDを持つコンポーネント(もしあれば)を見つけるために使用される、"相対的" 検索式になりました。マッチは次のように行われます。
- 検索式が単純な識別子の場合、この値は id プロパティと比較され、その後、ファセットおよびベースの子プロパティを再帰的に検索します。
UIComponent
(ただし、子孫のNamingContainer
が見つかった場合、それ自身のファセットと子は検索されない)。- 検索式がセパレータ文字で区切られた複数の識別子を含む場合、最初の識別子を用いて
NamingContainer
は、前の箇条書きにある規則によって そして、そのfindComponent()
メソッドで、このNamingContainer
が呼び出され、検索式の残りが渡されます。
PrimeFacesもJSFの仕様に準拠していますが、RichFacesでは "いくつかの追加の例外"。 .
"reRender"。 用途
UIComponent.findComponent()
アルゴリズム(いくつかの追加的な例外を除く)を使用して、コンポーネントツリーでコンポーネントを見つけます。
これらの追加的な例外はどこにも詳しく説明されていませんが、相対的なコンポーネントID(つまり、そのIDが
:
のコンテキストで検索されるだけでなく、最も近い親である
NamingContainer
のみならず、他のすべての
NamingContainer
コンポーネントを作成します (ちなみにこれは比較的コストのかかる作業です)。
を使用しないでください。
prependId="false"
これでもまだうまくいかない場合は、次の手順で
<h:form prependId="false">
. これは、ajax送信とレンダリングの処理中に失敗します。この関連する質問も参照してください。
UIForm with prependId="false" breaks <f:ajax render>.UIForm with prependId="false" breaks <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セレクタ(PFS)
のように
@(.someclass)
を使用すると、jQuery CSS セレクタ構文でコンポーネントを参照することができます。例えば、HTML出力ですべて共通のスタイルクラスを持つコンポーネントを参照することができます。これは、特に多くのコンポーネントを参照する必要がある場合に便利です。これは、対象となるコンポーネントが、HTML出力においてすべてのクライアントID(固定または自動生成、問題なし)を持っていることのみを前提条件とします。以下も参照してください。
update="@(.myClass)" のようなPrimeFacesセレクタはどのように機能するのですか?
関連
-
[解決済み] AJAX使用時にGoogle Maps APIが "Uncaught ReferenceError: google is not defined "を投げる。
-
ajax リクエストが Uncaught TypeError を報告しました。不正な呼び出しエラー
-
AjaxにおけるbeforeSend関数の使用について
-
リソースの読み込みに失敗しました:サーバーはステータス 400 (Bad Request) で応答しました。
-
[解決済み] JSONまたは部分的なhtmlを返すASP.NET MVCコントローラのアクション
-
[解決済み】プリフライトCORSリクエストの導入の動機は何ですか?
-
[解決済み] jQuery AJAXリクエストをキャンセル/中止する方法は?
-
[解決済み】WebSocketが使えるのに、なぜAJAXを使うのか?
-
[解決済み】「for (;;); { json data }」のようなAjax呼び出し応答は何を意味するのでしょうか?[重複している]。
-
[解決済み] WebサーバーからブラウザにデータをPUSHする方法はありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Google Maps APIがAJAX使用時のみ「Uncaught ReferenceError: google is not defined」を投げる。
-
リソースの読み込みに失敗しました:サーバーはステータス 400 (Bad Request) で応答しました。
-
[解決済み] 一般的なブラウザでは、AJAX(XmlHttpRequest)の同時リクエストはいくつまで可能ですか?
-
[解決済み】一部のAJAXコールで "net::ERR_BLOCKED_BY_CLIENT "エラーが発生する。
-
[解決済み】AJAXレスポンスはクッキーを設定することができますか?
-
[解決済み】Chromeでのリクエストモニタリング
-
[解決済み】jQuery: 同期AJAXリクエストの実行
-
[解決済み】ko.applyBindingsを呼び出して部分ビューをバインドすることはできますか?
-
[解決済み] AJAXアプリのアドレスバーのURLを現状に合わせて変更する
-
[解決済み] ajax更新/レンダーのためのコンポーネントのクライアントIDを見つける方法?bar "から "foo "を参照する式でコンポーネントを見つけることができません。