6

私は、グーグルのもののように、フレームを使って、ある種の単純なカスタマイズ可能なニュースビューページを私のウェブアプリケーションにしようとしています。各フレームオブジェクトには、コンテンツとして追加されるタイトルとURLがあります。

私はJSFとprimefacesを両方とも最新バージョンで使用しています。したがって、私のバッキングBeanは@ViewScoped、Beanに格納されているログに記録されたユーザーにアクセスでき、@SessionScopedそのユーザーは対応するフレームをロードします。

Beanに対して反復しようとすると問題が発生します。これは、タグ@ViewScopedを使用するしか方法がないためです。c:forEachそれが私のやり方です:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:form>
    <p:panel header="Noticias">
        <h:panelGrid columns="#{fn:length(navegableHomeManager._UserFrames)}"
            width="100%">
            <c:forEach var="frame" items="#{navegableHomeManager._UserFrames}">
                <p:column>
                    <p:panel header="#{frame._Name}" closable="true"
                        style="width:95%;height:500px;" id="#{frame._Name}">
                        <p:ajax event="close"
                            listener="#{navegableHomeManager.actionFrameClosed}" />
                        <ui:include src="#{frame._Path}" />
                    </p:panel>
                </p:column>
            </c:forEach>
        </h:panelGrid>
    </p:panel>
</h:form>

その反復は、navegableHomeManagerBeanであるため、明らかに動作しません@ViewScoped。したがって、Beanは各反復で再構築されます。私が到達した解決策は、との@SessionScoped間に別のBeanを使用するため、フレームがそこに格納され、反復でそれらに適切にアクセスできます。これは上記のコードで機能しています。navegableHomeManagerloggedBean

@SessionScopedただし、そのように反復するたびにBeanを使用する(ケースごとに特定のBeanを作成する)ことは必須ではないと思います。そのため、反復を回避するためにコンポーネントを使用しようとしました。

<p:dataGrid columns="#{fn:length(navegableHomeManager._UserFrames)}"
            value="#{navegableHomeManager._UserFrames}" var="frame">
    <p:column>
        <p:panel header="#{frame._Name}" closable="true"
                    style="width:95%;height:500px;">
            <p:ajax event="close"
                        listener="#{navegableHomeManager.actionFrameClosed}" />
            <ui:include src="#{frame._Path}" />
        </p:panel>
    </p:column>
</p:dataGrid>

@ViewScopedBeanがまたはの場合も機能しません@SessionScoped。フレームのプロパティが設定されていても、ui:includeタグは宛先パスなしですでに作成されているため、宛先パスを動的にレンダリングすることはできません。ui:include同時に適用されているように、タグc:forEachを使用することc:forEachが実際にこれを通過する唯一の方法だと思います。

あなたのアイデアをプールします。

アップデート

ここでは、コンテキストの理解に役立つxhtmlコードをさらに投稿します。新しいページはテンプレートに統合されています。これが対象となるページです(/system/home/index.xhtml):

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
template="/templates/general_template.xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">

<ui:define name="metadata">
    <f:event type="preRenderView"
        listener="#{navegableHomeManager.initialize}" />
</ui:define>

<ui:define name="general_content">
    <ui:include src="/system/home/home_view.xhtml" />
</ui:define>

そして、それは私もそれをやろうとした方法ですが、c:forEachタグを機能させることはしませんでした:

<context-param>
    <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
    <param-value>/system/home/index.xhtml</param-value>
</context-param>

これがバッキングBeanヘッダーです。

@ManagedBean
@ViewScoped
@URLMapping(id = "home", pattern = "/home", viewId = "/system/home/index.xhtml")
public class NavegableHomeManager extends SystemNavegable {

/**
 * 
 */
private static final long serialVersionUID = 6239319842919211716L;

@ManagedProperty(value = "#{loggedBean}")
private LoggedBean _LoggedBean;

//More stuff
4

1 に答える 1

6

に固執し<c:forEach>ます。それはあなたが探している仕事をします。ビューの<ui:include>ビルド時に実行されるため、反復タグもビューのビルド時に実行する必要があります。

Beanの問題に関しては、次の@ViewScoped2つのオプションがあります。

  1. 特定のビューの部分的な状態保存をオフにします。

    <context-param>
        <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
        <param-value>/news.xhtml</param-value>
    </context-param>
    
  2. @RequestScopedこれをBeanに変更し、リクエストパラメータによってポストバック全体で状態を維持するために使用<f:param>します。@ManagedProperty

JSF 2.2が利用可能な場合は、3番目のオプションがあります。JSF2.2にアップグレードするだけです。ビュースコープのBeanと部分的な状態の保存における鶏が先か卵の問題を修正しました。

于 2013-01-28T12:02:44.327 に答える