2

特定のタグがカスタム コンポーネントのサブツリーにある場合に、jsf スレッドを特定の状態にセットアップすることを目指しています。このカスタム コンポーネントは、カスタム cdi スコープを宣言します。

<my:scope area="info">
    <rich:tree selectionChangeListener="#{taskTreeManager.selectionChanged}"
<my:scope>

<my:scope area="work">
    <rich:tree selectionChangeListener="#{taskTreeManager.selectionChanged}"
<my:scope>

ここに私の考えがあります: cdi bean 'taskTreeManager' は、カスタム cdi スコープから来ているため、2 つの rich:tree で異なります。

@TaskScoped
public TaskTreeManager { .... } 

今、私は jsf タグを作成しました。

欠けているのは、このタグがその子に影響を与える方法、つまり一般的な方法です (つまり、仮定を作成せず、子を変更する必要がありません)。

サブツリー内の任意のタグで発生する各アクションで cdi スコープをアクティブにする必要があります。

また、特に Ajax 呼び出しは、まさにコンポーネント (rich:tree) で定義されたリスナーに直接アクセスするため、そのためのリスナーを見つけることもできませんでした。xhtml に表示されるコンポーネントの階層はあまり関係がないため、taskTreeManager.selectionChanged が呼び出されたときに my:scope タグが認識されないため、cdi スコープを適切に切り替えることができません。

次に、サブツリーに存在する各コンポーネントにリスナーをプログラムでセットアップしようとしました。

それまでの間、私は振り返りました: 私が達成しようとしているのは、各 Java コールバックが正しいスコープをアクティブにすることです。これは次のように要約できます。各 EL 式の評価は、適切なスコープでその cdi Bean を見つけます。そこで私のやり方は、現在のコンポーネントがタグ内にあるかどうかを発見することだけを目的として、新しい ELResolver を導入することでした。

幸いなことに、それは可能です:

   private String computeViewArea(UIComponent cc) {
    String retval = EMPTY;
    while (null != cc) {
        // attention: cc.toString() causes stackoverflow !! so don't log cc!
        if (cc instanceof TaskScopedComponent) {
            TaskScopedComponent c = (TaskScopedComponent) cc;
            retval = (String) c.getAttributes().get("viewArea");
            break;
        }
        cc = cc.getParent();
    }
    return retval;
}
4

0 に答える 0