2012-08-14 4 views
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), ни afterPhase(PhaseEvent) методы называются в любом случае, будь это полная или частичная загрузка страницы.

Я помню эту ошибку здесь: http://java.net/jira/browse/JAVASERVERFACES-1200, но, похоже, это было исправлено довольно давно.

Я использую GlassFish 3.1.2.2 на Java 6u33 x64.

ответ

1

#{cc} повторно оценивали каждый раз, когда beforePhase() или afterPhase() метод <f:phaseListener> фактически должен быть выполнен с помощью UIViewRoot. #{cc} в данный момент недоступен в области EL. Он доступен только в пределах области действия компонента.

Он отлично работает, если 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_FAMILY константа вместо жесткого кодирования "javax.faces.NamingContainer".

+0

Ugh ... И я думал, что получаю верх над этим жизненным циклом. Да, это работает, и это достаточно чисто. Спасибо за дополнительный совет. Это просто постоянный, который я искал. –

+0

Добро пожаловать. – BalusC

 Смежные вопросы

  • Нет связанных вопросов^_^