【问题标题】:JSF 2 equivalent of IBM's hx:scriptCollector pre- and postRenderJSF 2 等效于 IBM 的 hx:scriptCollector pre-和 postRender
【发布时间】:2012-10-29 08:27:17
【问题描述】:

我正在将旧的 JSF 应用程序从 WebSphere 迁移到 JBoss:旧版本使用 JSF 的 IBM 实现。我的问题涉及以下组件:

<hx:scriptCollector id="aScriptCollector"
        preRender="#{aBean.onPageLoadBegin}" postRender="#{aBean.onPageLoadEnd}">

为了重现 JSF 2 中的 preRender 行为,我使用了表单绑定(s.here)。我的问题:

1) 你知道在 JSF 2 中模拟 postRender 的技巧吗?

2) 你认为我在 preRender "clean" 中使用的技巧是什么?

非常感谢您的帮助! 再见

【问题讨论】:

    标签: jsf jsf-2 websphere


    【解决方案1】:

    最接近你可以实现完全相同的钩子是

    <f:view beforePhase="#{bean.beforePhase}" afterPhase="#{bean.afterPhase}">
    

    public void beforePhase(PhaseEvent event) {
        if (event.getPhaseId == PhaseId. RENDER_RESPONSE) {
            // ...
        }
    }
    
    public void afterPhase(PhaseEvent event) {
        if (event.getPhaseId == PhaseId. RENDER_RESPONSE) {
            // ...
        }
    }
    

    preRender 可以以更简单的方式实现,将其放在您的视图中的任何位置:

    <f:event type="preRenderView" listener="#{bean.preRenderView}" />
    

    public void preRenderView(ComponentSystemEvent event) {
        // ...
    }
    

    (参数是可选的,如果不使用可以省略)


    没有postRenderView 这样的东西,但您可以轻松创建自定义事件。例如

    @NamedEvent(shortName="postRenderView")
    public class PostRenderViewEvent extends ComponentSystemEvent {
    
        public PostRenderViewEvent(UIComponent component) {
            super(component);
        }
    
    }
    

    public class PostRenderViewListener implements PhaseListener {
    
        @Override
        public PhaseId getPhaseId() {
            return PhaseId.RENDER_RESPONSE;
        }
    
        @Override
        public void beforePhase(PhaseEvent event) {
            // NOOP.
        }
    
        @Override
        public void afterPhase(PhaseEvent event) {
            FacesContext context = FacesContext.getCurrentInstance();
            context.getApplication().publishEvent(context, PostRenderViewEvent.class, context.getViewRoot());
        }
    
    }
    

    您在faces-config.xml 中注册为

    <lifecycle>
        <phase-listener>com.example.PostRenderViewListener</phase-listener>
    </lifecycle>
    

    那么你终于可以使用了

    <f:event type="postRenderView" listener="#{bean.postRenderView}" />
    

    public void postRenderView(ComponentSystemEvent event) {
        // ...
    }
    

    【讨论】:

    • 嗨,BalusC!非常感谢您的回答,照常照亮! :) 不幸的是,我在调用 postRenderView() 方法时遇到问题。我完全按照你写的做了,但它没有被调用。如果我在我的 f:event 代码中将 type="postRenderView" 替换为“preRenderView”,则该方法会被调用(当然就好像它是 preRenderView).. PostRenderViewListener 的 afterPhase() 也会被调用。我错过了什么吗?再次感谢!
    • &lt;f:event&gt; 是否包含在 &lt;f:metadata&gt; 中?这样,它将附加到UIViewRoot(在publishEvent() 调用中传递)。否则,您需要遍历整个组件树并为视图树的所有单个组件发布它,这相对昂贵。 preRenderView 作为标准事件类型已被 UIComponent 特殊处理,因此不必将其放置在 &lt;f:metadata&gt; 中以便直接附加到 UIViewRoot
    • 不,它没有包含在 f:metadata 中(至少是明确的?):无论如何,我只是将构造函数更改为 public PostRenderViewEvent(UIViewRoot component) {super(component);} 现在可以工作了。这样对吗?
    • 哦!那也可以:)很好的发现。
    猜你喜欢
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    相关资源
    最近更新 更多