2009-06-03 6 views
0

私の管理Bean:のForEachとFaceletsの

public List<String> getLiQuickNav(){ 

    System.out.println("I'm here..."); 

    List<String> l = new ArrayList<String>(); 
    l.add("toto"); 
    l.add("tata"); 
    l.add("titi"); 
    return l; 
} 

私のforEach:

<c:forEach var="categorie" items="#{mainControleur.liQuickNav}"> 
    <h:outputLabel value="${categorie}"/> 
</c:forEach> 

私の出力ストリーム:私がここにいる
私がここにいる
... ...
私がここにいる...
私がここにいる...

「getLiQuickNav()」は私のForEachによって4回呼び出されます。しかし、私はちょうど "getLiQuickNav()"を呼び出すwan'tを1回... どのようにそれを一度呼び出すには?

ボーナスに関する質問: 「getLiQuickNav()」は4時間かけて呼び出されるのに対し、「タタ、ティティ、トト」は3つしかないのはなぜですか?

感謝の

答えて

3

あなたはgetLiQuickNav()が呼び出される回数を制御することはできません - それは呼び出しの間で再構築されていませんので、あなたのリストをキャッシュすることを検討してください。

private List<String> l; 

public List<String> getLiQuickNav() 
{ 
    if (l == null) 
    { 
      System.out.println("I'm here..."); 

      l = new ArrayList<String>(); 
      l.add("toto"); 
      l.add("tata"); 
      l.add("titi"); 
    } 
    return l; 
} 

同様にあなたは<ui:repeat/>ではなく、<c:forEach/>を使用する必要があります。理由は、blogのエントリを参照してください。

+0

私は上記のようなものは一般的には良い練習ではないと思います。 3つの項目で何かを怠惰に初期化する理由はありません。コンストラクタまたは静的ブロックにリストを構築します。 – GreenieMeanie

+0

@GreenieMeanie - これは明らかに簡単な例です。実際のリストデータは、オブジェクトの構築や静的ブロックの初期化(つまり、データベースなどの外部ソースから取得した場合)で利用できない可能性があります。その答えは、getLiQuickNav()を呼び出すたびにリストの作成を行うべきではないことを説明するためのものです。 – mtpettyp

2

回答

ゲッターで状態を毎回再初期化しています。これはアクセサを意味し、状態を初期化する方法ではありません。 getLiQuickNavでリストを作成せず、コンストラクターまたはセッターで作成します。

ボーナス

あなたがリストを初期化するgetLiQuickNav()呼び出す最初の時間は、このリストへの参照が返され、保存された範囲にあなたの式(.liQuickNav)を評価し、その後getLiQuickNav()はコンベンション3以上によって呼び出されますリスト内の各項目の時間。

毎回同じリストを返すと、1度呼び出されるはずです。あなたは毎回新しいものを返しています。

2

ゲッターズ・イン・ジャパン(どんなコンテキストでも、Faces Managed Beansに含める)は何も生成すべきではありません。値を返すだけです。手前にリストを作成して返します。

関連する問題