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,但它似乎已经在很久以前修复了。

我在 Java 6u33 x64 上使用 GlassFish 3.1.2.2。

4

1 回答 1

1

#{cc}每次实际beforePhase()需要afterPhase()由. _ 目前在 EL 范围内不可用。它仅在组件的范围内可用。<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);
}

与具体问题无关,最好使用UINamingContainer.COMPONENT_FAMILYconstant 而不是 hardcoding "javax.faces.NamingContainer"

于 2012-08-14T21:36:54.097 回答