Question

Je vais avoir un problème.

Je l'ai mis en place un PhaseListener, qui vise à ajouter une classe de style à tous les composants UIInput dans l'arborescence qui ont des messages qui leur sont rattachés, et supprime la classe de style si elle n'a pas de messages qui leur sont rattachés.

Le PhaseListener court dans la phase RENDER_RESPONSE, et ne c'est le travail dans les deux méthodes beforePhase et afterPhase pendant le débogage. Bien que le débogage, je trouve que beforePhase n'a pas accès à l'arbre complet du composant, mais afterPhase fait. Toute modification apportée à afterPhase ne sont pas rendus bien.

Comment puis-je cela? Je veux que ce soit complètement côté serveur.

Merci,

James

Était-ce utile?

La solution 2

Mis en œuvre en utilisant un ViewHandler, mais il est pas efficace. PhaseListener en rendu la phase de réponse n'a pas accès à l'arborescence des composants.

Autres conseils

L'arborescence des composants JSF est disponible après le moment de la construction de la vue. La phase RENDER_RESPONSE est pas nécessairement un bon moment pour avoir accès à l'arbre complet des composants JSF avant qu'il ne soit rendu. Au cours d'une première demande GET sans <f:viewAction>, l'arbre complet du composant est disponible uniquement dans le afterPhase comme il est en cours de construction au cours de la RENDER_RESPONSE. Au cours d'un postback l'arbre complet du composant est disponible dans beforePhase, cependant, quand une navigation à une autre vue a eu lieu, il serait Stil changer pendant la phase de RENDER_RESPONSE, de sorte que toute modification me perdrais .

Pour en savoir exactement ce que le temps de construction de vue est, la tête à la question Quel est le temps de construction de vue

Vous voulez essentiellement à accrocher « vue de rendre le temps » plutôt que beforePhase de phase RENDER_RESPONSE. JSF offre plusieurs façons de crochet sur elle:

  1. Dans certains modèle maître, attacher un écouteur d'preRenderView à <f:view>.

    <f:view ...>
        <f:event type="preRenderView" listener="#{bean.onPreRenderView}" />
        ...
    </f:view>
    
    public void onPreRenderView(ComponentSystemEvent event) {
        UIViewRoot view = (UIViewRoot) event.getSource();
        // The view is the component tree. Just modify it here accordingly.
        // ...
    }        
    
  2. Ou, mettre en œuvre un SystemEventListener PreRenderViewEvent .

    public class YourPreRenderViewListener implements SystemEventListener {
    
        @Override
        public boolean isListenerForSource(Object source) {
            return source instanceof UIViewRoot;
        }
    
        @Override
        public void processEvent(SystemEvent event) throws AbortProcessingException {
            UIViewRoot view = (UIViewRoot) event.getSource();
            // The view is the component tree. Just modify it here accordingly.
            // ...
        }
    
    }
    

    Pour le faire fonctionner, inscrivez-vous comme ci-dessous faces-config.xml:

    <application>
        <system-event-listener>
            <system-event-listener-class>com.example.YourPreRenderViewListener</system-event-listener-class>
            <system-event-class>javax.faces.event.PreRenderViewEvent</system-event-class>
        </system-event-listener>
    </application>
    
  3. Ou, fournir une coutume ViewHandler dans laquelle vous faites le travail dans renderView() .

    public class YourViewHandler extends ViewHandlerWrapper {
    
        private ViewHandler wrapped;
    
        public YourViewHandler(ViewHandler wrapped) {
            this.wrapped = wrapped;
        }
    
        @Override
        public void renderView(FacesContext context, UIViewRoot view) {
            // The view is the component tree. Just modify it here accordingly.
            // ...
    
            // Finally call super so JSF can do the rendering job.
            super.renderView(context, view);
        }
    
        @Override
        public ViewHandler getWrapped() {
            return wrapped;
        }
    
    }
    

    Pour le faire fonctionner, inscrivez-vous ci-dessous dans faces-config.xml:

    <application>
        <view-handler>com.example.YourViewHandler</view-handler>
    </application>
    
  4. Ou, crochet sur OmniFaces a a <o:highlight> composante qui fait exactement cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top