10

JSFで非常に単純なタスクを実行するのに大きな問題があります。問題: オブジェクトごとにタイプが異なる可能性のある集約されたプロパティを持つオブジェクトがあります。プロパティのタイプに応じて、異なる入力フィールドのセットを使用したいと考えています。

サブタイプ コンポーネントはフレームワークに存在し、オンデマンドで読み込まれます。このために、次のコードを使用します。

<h:panelGroup id="zusatzdaten">
    <fieldset class="clear">
    <legend>#{tickerUI.ticker.tickerDescription.label}
          (#{tickerUI.ticker.tickerDescId})
    </legend>
    <h:panelGroup rendered="#{tickerUI.editComponentName != null}">
        <ui:include src="#{tickerUI.editComponentName}"/>
    </h:panelGroup>
    </fieldset>
</h:panelGroup>

コンポーネントの名前は、@SessionScope の TickerUI に由来します。目を見張るようなビット: 最初のロード時に、正しいサブコンポーネントが表示されます。ただし、ナビゲーションでリンクを使用すると、別のコンポーネントが含まれるはずですが、コンテンツは更新されません! データは別のサブタイプになりましたが、フォーム コンポーネントは以前のもののままであるため、これはエラーになります。

エラーから戻って再度リンクをクリックすると、正しいコンポーネントが表示されます。editComponentName の値をログに記録したところ、正しい値が返されました。これは非常に紛らわしいです。ゲッターが正しいコンポーネント名を の src 属性に返すときに、誤ったコンテンツを含めるのはなぜですか?

大変助かります。

4

2 に答える 2

8

実際、あなたの問題は、従来のビューのビルドとビューのレンダリング時間の問題/誤解です。より具体的には、ビューは新しいリクエストごとに構築され、ポストバック時に以前に保存された状態から再構築されます。その後、ビューがレンダリングされて HTML コンテンツが生成されます。

これで<ui:include>タグ ハンドラー、または正式な用語ではビュー ビルド時のタグと同様に、最初にページをリクエストすると、そのvalue属性が評価され、含まれているページがビューに入ります。ポストバックすると、予想に反して、含まれているコンテンツが再構築されたビューに既に存在します。したがって、ビューの正確な部分がレンダリングされるのは、予期される動作です。

<ui:fragment>解決策としては、条件付きでレンダリングされたJSF コンポーネントにラップされた静的インクルードの完全なリストを単純に含めることができます。簡単にするために、すべてのコンテンツは<h:panelGroup>、AJAX 更新を容易にするために常にレンダリングされるようなコンテナー内に配置できます。コードは次のように組み立てることができます。

<h:panelGroup id="ui">
    <ui:fragment rendered="#{bean.condition1}">
        <ui:include src="/path/to/file1.xhtml"/>
    </ui:fragment>
    ...
    <ui:fragment rendered="#{bean.condition_n}">
        <ui:include src="/path/to/file_n.xhtml"/>
    </ui:fragment>
</h:panelGroup>
于 2013-04-23T15:27:48.240 に答える
1

古典的なジレンマのようです。BalusC のブログでは、web.xml の構成パラメーターの形式で私の場合の解決策を示しました。

<context-param> 
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> 
    <param-value>false</param-value>
</context-param>
于 2013-04-23T15:46:59.787 に答える