8

いくつかのアクションに応じてページフラグメントを条件付きでレンダリングするために、webapp のいくつかの場所に次の構造があります。

<h:panelGroup rendered="#{managedBean.serviceSelected == 'insurance'}">
    <ui:include src="/pages/edocket/include/service1.xhtml" />
</h:panelGroup>

属性が評価<ui:include>されても が実行されることを確認しました。これにより、インクルードされたファイルに関連付けられたすべてのバッキング Bean が不必要に作成されます。renderedfalseservice1.xhtml

親 UI コンポーネントがレンダリングされていないときに の実行をスキップ<ui:include>して、これらすべてのバッキング Bean が不必要に作成されないようにするにはどうすればよいですか?

4

2 に答える 2

9

残念ながら、これは仕様です。はビューの<ui:include>ビルド時にタグ ハンドラとして実行されますが、rendered属性はビューのレンダリング時に評価されます。<ui:include>これは、この回答を注意深く読み、「JSTL」を「 」に置き換えることで、よりよく理解できます。JSF2 Facelets の JSTL... 意味はありますか?

具体的な機能要件に応じて、これを解決する方法がいくつかあります。

  1. <c:if>の代わりにビューのビルド時間タグを使用します<h:panelGroup>。ただし、これは に影響を与え#{managedBean}ます。ビュー スコープにすることはできず、HTTP 要求パラメーターに基づいてジョブを実行する必要があります。これらの HTTP 要求パラメーターは、ビューが復元されたときに壊れないように、後続の要求 ( などによる)<f:param>でも保持する必要があります。includeViewParams

  2. メソッド中に呼び出す<ui:include>カスタムに置き換えます。これまでのところ、そのようなコンポーネントは既存のライブラリには存在しません。しかし、私はOmniFacesの将来の追加としてすでにそのようなものを念頭に置いており、ここで私のテスト環境 (Mojarra を使用) で直感的に期待どおりに動作することがわかります。キックオフの例を次に示します。UIComponentFaceletContext#includeFacelet()UIComponent#encodechildren()

    @FacesComponent(Include.COMPONENT_TYPE)
    public class Include extends UIComponentBase {
    
        public static final String COMPONENT_TYPE = "com.example.Include";
        public static final String COMPONENT_FAMILY = "com.example.Output";
    
        private enum PropertyKeys {
            src;
        }
    
        @Override
        public String getFamily() {
            return COMPONENT_FAMILY;
        }
    
        @Override
        public boolean getRendersChildren() {
            return true;
        }
    
        @Override
        public void encodeChildren(FacesContext context) throws IOException {
            getChildren().clear();
            FaceletContext faceletContext = ((FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY));
            faceletContext.includeFacelet(this, getSrc());
            super.encodeChildren(context);
        }
    
        public String getSrc() {
            return (String) getStateHelper().eval(PropertyKeys.src);
        }
    
        public void setSrc(String src) {
            getStateHelper().put(PropertyKeys.src, src);
        }
    
    }
    
于 2012-08-16T16:47:48.880 に答える
6

条件式を ui:include src: として使用します。

<h:panelGroup>
    <ui:include 
        src="#{managedBean.serviceSelected == 'insurance' ?
            '/pages/edocket/include/service1.xhtml'
            :
            '/pages/empty.xhtml'}"
    />
</h:panelGroup>
于 2013-02-21T22:13:38.807 に答える