1

複合コンポーネントがあります:

<cc:interface componentType="com.example.MyComponent">
    <!-- ... -->
</cc:interface>

<cc:implementation>
    <f:phaseListener binding="#{cc}"/>
    <div id="#{cc.clientId}">
        <!-- ... -->
    </div>
</cc:implementation>

そしてそのクラス:

@FacesComponent("com.example.MyComponent")
public class MyComponent extends UIOutput implements NamingContainer, PhaseListener
{
    @Override
    public String getFamily()
    {
        return "javax.faces.NamingContainer";
    }

    @Override
    public PhaseId getPhaseId()
    {
        return PhaseId.ANY_PHASE;
    }

    @Override
    public void beforePhase(PhaseEvent event)
    {
        // Do something ...
    }

    @Override
    public void afterPhase(PhaseEvent event)
    {
        // Do something ...
    }
}

ページの完全な読み込みでも部分的な読み込みでも、beforePhase(PhaseEvent)norafterPhase(PhaseEvent)メソッドは呼び出されません。

ここでこのバグに注意します:http://java.net/jira/browse/JAVASERVERFACES-1200、しかしそれはかなり前に修正されたようです。

Java6u33x64でGlassFish3.1.2.2を使用しています。

4

1 に答える 1

1

は、またはの メソッドが によって実際に実行される必要がある#{cc}たびに再評価されます。現時点では、EL スコープでは使用できません。コンポーネントのスコープ内でのみ使用できます。beforePhase()afterPhase()<f:phaseListener>UIViewRoot#{cc}

binding複合コンポーネントのコンストラクターで次のように、少なくとも要求スコープの変数を指している場合は正常に機能します。

public MyComponent() {
    FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("ccc", this);
}

<f:phaseListener binding="#{ccc}" />

もちろん、この構造は、このタイプの複合コンポーネントが複数ある場合にのみ失敗します。

別のアプローチを探す方がよいでしょう:<f:phaseListener>完全に取り除きUIViewRoot#addPhaseListener()、複合コンポーネントのコンストラクターで使用するだけです:

public MyComponent() {
    FacesContext.getCurrentInstance().getViewRoot().addPhaseListener(this);
}

具体的な問題とは関係ありませんが、 hardcoding の代わりに constant を使用することUINamingContainer.COMPONENT_FAMILYをお勧めし"javax.faces.NamingContainer"ます。

于 2012-08-14T21:36:54.097 に答える