かなり普通のケース:
拡張と折りたたみの2つの状態を持つ「ポートレット」複合コンポーネントがあります。ポートレットは展開された状態で開始されますが、ユーザーはそれらをクリックして折りたたむことができます。この状態はセッションに保存する必要があります。これにより、ユーザーがページを更新するか、新しいページに移動すると、ポートレットは展開/折りたたみされているかどうかを記憶します。
これが問題の核心です。ページに複数回挿入できるこのような状態保存をコンポーネントに実際にどのように実装しますか?
いくつかの背景/アイデア:
1つのポートレットに状態保存を実装するには、セッションスコープのBeanを使用することで簡単に実現できます。また、固定数のセッションスコープBeanを作成するか、1つのBeanに異なるプロパティを宣言することで、固定数のポートレットをサポートできます。しかし、なぜそれらのアプローチが悪いのかについても言及したくありません。
これについての私の最初のアイデアは、すべてのポートレットの状態を保持するために、単一のセッションBeanの下にマップ(またはいくつかのオブジェクト構造)を作成することでした。ただし、JSFからこのデータを直接参照することはできません(JSFもそれらを更新するため)。マップ内の正しい値をフェッチ/更新するために特定のゲッター/セッターを作成することを検討しましたが、ゲッターとセッターの実行中に識別データがないため、それは不可能です。
ただし、状態をセッションBeanに保存する必要があることはおそらく明らかです。f:ajax
フォームを投稿し、送信されたデータを使用して特別なメソッドを実行することで、状態の保存を非常に簡単に行うことができlistener
ます。コンポーネントの複数のインスタンスをサポートするために、リクエストスコープのBean(の複数のインスタンス)を使用して、各展開/折りたたみを処理できます。ただし、ポートレットとその状態を識別するデータを実際に投稿するには、最初にレンダリング時にフォームフィールドにデータを挿入する必要があります。
では、レンダリング時に各ポートレットに適切なデータを実際に提供するにはどうすればよいでしょうか(実際には、この場合はブール値/列挙型を指定しますが、より多くのデータを処理する必要がある場合を考えてみてください)。
のようだ:
h:inputHidden
またh:inputText
、value-attribute(を指す)以外の初期値の設定はサポートされていません#{portletBean.portletState}
。- 利用可能な識別情報がないため、作成時に正しい初期値でリクエストBeanを自動ロードできません。
もう一度、何かが足りないように感じます...ポインタ?
答えの少なくとも1つは、UIComponent
複合コンポーネントではなく使用することだと思いますが、生のHTML要素がたくさん含まれているため、これを複合コンポーネントとして保持したいと思います。
アップデート:
- ビュースコープのBeanを使用することを提案する、かなり類似した質問があります。ただし、これはここでは実行可能ではないと思います。