<ui:include>、タグファイル、複合コンポーネント、および/またはカスタムコンポーネントをいつ使用しますか?


102

私は最近FaceletsでJSF 2.0を使い始め<ui:include>、Facelets 1.xが提供する既存およびその他のテンプレート技術を知っている新しい複合コンポーネントに戸惑いました。

これらのアプローチの違いは何ですか?機能的には、ほぼ同じように提供されているようです:<ui:param>vs <cc:attribute><ui:insert>+ <ui:define>vsタグファイル、既存のテンプレートの再利用。複合コンポーネントの場合、構文と明確なインターフェース仕様以外に何かありますか?パフォーマンスは異なりますか?

回答:


176

これらのアプローチの違いは何ですか?

Faceletテンプレート

メインページレイアウトフラグメントを再利用可能なテンプレートに分割する場合は<ui:composition>、Faceletテンプレートを使用します(<ui:include>およびのように<ui:decorate>)。たとえば、ヘッダー、メニュー、コンテンツ、フッターなど。

例:

Faceletタグファイル

コードの重複を防止/最小化するために再利用可能なコンポーネントのグループが必要な場合は、Faceletタグファイルを使用します。たとえば、label + input + messageコンポーネントのグループ。複合コンポーネントとの主な違いは、Faceletタグファイルの出力が単一UIComponentを表さず、状況によっては、複合コンポーネントでは不十分な場合の唯一の解決策になる場合があります。一般に、マネージドBeanプロパティを渡す(ハードコードされた値ではない)<ui:include>1つ以上のwith <ui:param>は、インクルードファイルがタグファイルである可能性が高いことを示しています。

例:

複合コンポーネント

UIComponent純粋なXMLを使用して単一の責任を持つ単一の再利用可能なカスタムを作成する場合は、複合コンポーネントを使用します。このような複合コンポーネントは通常、既存のコンポーネントやHTMLの集まりで構成され、物理的に単一のコンポーネントとしてレンダリングされ、単一のBeanプロパティにバインドされることになっています。例えば、単一表すコンポーネントjava.util.Date3つの依存性による<h:selectOneMenu>コンポーネント、または組み合わせたコンポーネント<p:fileUpload><p:imageCropper>単一に<my:uploadAndCropImage>単一のカスタム参照com.example.Imageプロパティとしてエンティティ。

例:

カスタムコンポーネント

コンポーネントの標準/利用可能なセットでのサポートがないため、Faceletタグファイルまたは複合コンポーネントで機能を実現できない場合は、カスタムコンポーネントを使用してください。例は、PrimeFacesOmniFacesなどのオープンソースコンポーネントライブラリのソースコードのあらゆる場所にあります

タグハンドラー

HTML出力のレンダリングではなく、JSFコンポーネントツリーの構築を制御する場合は、コンポーネントの代わりにタグハンドラーを使用する必要があります。

例:

プロジェクトの例

上記の手法をすべて利用するプロジェクトの例をいくつか示します。


パフォーマンスは異なりますか?

技術的には、パフォーマンスの問題は無視できます。選択は、具体的な機能要件と、実装の抽象化、再利用性、保守性の最終的な度合いに基づいて行う必要があります。それぞれのアプローチには、明確に定義された独自の目的と制限があります。

ただし、複合コンポーネントには、ビューの構築/復元時(特に、ビュー状態の保存/復元時)に大きなオーバーヘッドがあります。また、古いバージョンのMojarraでは、複合コンポーネントにデフォルト値の割り当てに関するパフォーマンスの問題がありました。これは2.1.13以降ですでに修正されています。また、Mojarraでa をメソッド式に使用すると、メモリリークが発生しました<cc:attribute method-signature>。基本的に、コンポーネントツリー全体がHTTPセッションで再参照されます。これは、2.1.29 / 2.2.8以降で修正されています。メモリリークは、次のように古い2.1バージョンで回避できます。

<context-param>
    <param-name>com.sun.faces.serializeServerState</param-name>
    <param-value>true</param-value>
</context-param>

または、以下の古い2.2バージョンでは:

<context-param>
    <param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name>
    <param-value>true</param-value>
</context-param>

それでも、比較的「多くの」複合コンポーネントがあり、にjavax.faces.STATE_SAVING_METHOD設定したclient場合、パフォーマンスは面倒になります。単純なインクルードファイルまたはタグファイルですでに可能である基本的な機能だけが必要な場合は、複合コンポーネントを乱用しないでください。*.taglib.xmlタグファイルよりも複合コンポーネントを優先する言い訳として、設定の容易さ(読み取り:ファイルは不要)を使用しないでください。

Mojarra 2.2.10以前を使用する場合は、本番モードの比較的短いFacelets更新期間を無効にすることを忘れないでください。

<context-param>
    <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
    <param-value>-1</param-value>
</context-param>

この設定を開発に使用しないでください。そうしないと、サーバー全体を再起動してFaceletsファイルの変更を反映させる必要があります。Mojarra 2.2.11以降、およびMyFaces は、がに設定されていない-1場合のデフォルトになっjavax.faces.PROJECT_STAGEていDevelopmentます。


なぜ3(faceletタグファイル)ではなく、1コンポーネント(複合コンポーネント)をレンダリングするのですか?つまり、晴れた日には、3の代わりに1のように感じるかもしれません。あなたの例では、UINamingContainerを拡張しています...それが(いくつかのjsf実装固有の関数を上書きできるようにするために)ccを使用する理由の1つでしょうか?
Toskan 2012年

2
タグファイルは、一種のインクルードと見なす必要があります。複合コンポーネントは、実際のコンポーネントと見なす必要があります。複合コンポーネントを実装する必要がありますNamingContainer。そうしないと、同じコンポーネントが複数回再利用されるときに、IDの重複問題が発生します。
BalusC、2012年

@BalusCたとえば、アドレス(およびそのすべての属性:通り、番号、都市など)を追加または削除できる「ブロック」を作成する一連のHTMLおよびJSFがあるとします。同じブロックを2ページまたは3ページで使用する必要があります。それは複合コンポーネントの説明に該当しますか?
RinaldoPJr 2013

1
@Rinaldo:stackoverflow.com/questions/5713718/…に示されているように、動的に入力されるコンポーネントIDを含むタグファイルを使用すると思います。IMO、タグファイルで実行できる場合は、それを使用します。タグファイルではできない場合は、コンポジットを使用してください。単一のプロパティを操作するために複数のコンポーネントが必要な場合(住所ではなく、単一のプロパティに入るはずのstreetname + housenumberなど)、複合コンポーネントが唯一のソリューションになります。
BalusC 2013

2
@Tarik:コンポジットは、タグファイルと比較してオーバーヘッドが多くなります。つまり、パフォーマンスが低い。密接に関連する既存のコンポーネントのセットに基づいて単一のカスタムUIコンポーネントを作成する必要がある場合にのみ使用してください。これはタグファイルではできません。たとえば、ZEEF.comには1つのコンポジットしかありません。アップロード/ダウンロード/クロップ画像のオールインワンのもので、これはaoページ画像、プロフィール画像、リンクブロックヘッダー、画像ブロックなどで使用されます。これはImageプロパティにのみバインドされます豆。
BalusC、2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.