20

UIForm属性のみを取得したという事実の背後にある考え方について質問がありますprependIdNamingContainerインターフェイスで属性が指定されていないのはなぜですか? おそらく下位互換性のためだと言うでしょうが、互換性を壊して、そのインターフェースを実装するユーザーに、prependId のメソッドも実装させることをお勧めします。

コンポーネントの prependId に関する私の観点からの主な問題は、UIFormそれが壊れるfindComponent() ということです.prependIdNamingContainer

簡単な例を次に示します。

<h:form id="test" prependId="false">
  <h:panelGroup id="group"/>
</h:form>

panelGroup コンポーネントを取得したいときは、文字列"group"を methodに渡すことを期待しますfindComponent()が、何も見つからないため、"test:group"代わりに使用する必要があります。

それに関する具体的な問題は、 ajax を で使用する場合prependId="false"です。ajax タグは、属性の更新とプロセスで、値がコンテナーの名前付けを処理することを期待しています。それを使用するときに完全なIDまたはパスを指定する必要があるのは少し奇妙ですprependId="false"が、大丈夫です。

<h:form id="test" prependId="false">
  <h:panelGroup id="group"/>
</h:form>
<h:form id="test1" prependId="false">
  <h:commandButton value="go">
    <f:ajax render="test:group"/>
  </h:commandButton>
</h:form>

このコードは問題なくレンダリングされますが、panelGroup が見つからないため更新されません。renderIds の要素としてidPartialViewContextのみが含まれます。"group"これが予想されるかどうかはわかりませんが、おそらくそうですが、コードはわかりません。findComponent()パラメーターとして渡された式が"group"、メソッドがコンポーネントを見つけることを期待する場所であるため、メソッドがコンポーネントを見つけることができないところまで来ました"test:group"

findComponent()1 つの解決策は、この問題に対処するために私が選択した方法を自分で作成することです。このメソッドではNamingContainer、通常のようにプロパティ prependId が false に設定されているコンポーネントを処理しますUIComponentUIComponentprependId 属性を提供するすべてに対してそれを行う必要がありますが、それは悪いことです。リフレクションは、型の静的な定義を回避するのに役立ちますが、それでも本当にきれいな解決策ではありません。

もう 1 つの方法は、インターフェイスに prependId 属性を導入し、上記のように動作するようNamingContainerに の動作を変更することです。findComponent()

findComponent()最後に提案された解決策は、ajax タグの動作を変更して ID 全体を渡すことですが、これは ajax の問題のみを解決し、実装の背後にあるプログラムの問題は解決しません。

それについてどう思いますか、なぜそのように実装されているのですか? この問題が発生したのは私が初めてではありませんが、関連するトピックを見つけることができませんでした?!

4

1 に答える 1

19

確かに、使用時UIComponent#findComponent()<f:ajax render>失敗したように<h:form prependId="false">。この問題は既知であり、「修正されません」: JSF 仕様の問題 573です。

私の謙虚な意見では、JSF 1.2 の時代にprependId属性を追加するべきではありませんでした。UIFormこれは単にj_security_check、JSF 入力コンポーネントを含む JSF フォームを使用したいユーザーを満足させるために行われたものです (j_security_check正確な入力フィールド名が必要j_usernamej_passwordあり、構成によって変更することはできません)。しかし、彼らは、JSF 1.2 の間に別の改善が導入されたことに正確には気づいていませんでし<form><h:form>。そして、CSS/jQuery の純粋主義者は、適切に選択されていない CSS セレクターでprependId="false"区切り文字をエスケープすることを避けるために悪用を開始します。:

決して使用しないでくださいprependId="false"

の場合は、または新しいサーブレット 3.0j_security_checkを使用してください。j_security_check を使用した Java EE/JSF でのユーザー認証の実行も参照してください。<form>HttpServletRequest#login()

CSS セレクターの場合、ID セレクターが絶対に必要な場合 (つまり、より再利用可能なクラス セレクターではない場合) は、目的のコンポーネントを単純な HTML<div>または<span>.

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

于 2011-09-14T13:04:29.727 に答える