【问题标题】:JSF Custom Component: How to get attribute of <f:ajax />JSF 自定义组件:如何获取 <f:ajax /> 的属性
【发布时间】:2011-11-08 06:05:15
【问题描述】:

我已经为 jsf 编写了一个自定义组件。渲染器扩展了 com.sun.faces.renderkit.html_basic.ListboxRenderer。我的组件在“javax.faces.SelectMany”-Family 中。

jsf-page中的代码如下:

<tb:myMenu id="testId" value="#{valueForm.someValue}">  
    <f:selectItem /> 
    <f:selectItems value="#{dao.getSomething()}"  />
    <f:ajax render=":myTestForm:myId"/>
</tb:myMenu>

如何在我的渲染器中获取渲染属性的值?我只需要值,不应该向我的组件写入任何内容(就像 RenderKitUtils-class 那样)

我目前的解决方案如下所示。它有效,但我对此并不满意。

if (component instanceof ClientBehaviorHolder) {
        Map<String, List<ClientBehavior>> behaviors = ((ClientBehaviorHolder)component).getClientBehaviors();
        if (behaviors != null && behaviors.keySet().contains("valueChange")) {
            for (ClientBehavior cb: behaviors.get("valueChange")) {
                if (cb instanceof AjaxBehavior) {
                    System.out.println("AJAX: " + ((AjaxBehavior) cb).getRender());
                }
            }
        }
    }

【问题讨论】:

    标签: java jsf jsf-2 components custom-component


    【解决方案1】:

    你到底有多不开心?太冗长了?好吧,JSF API 和 Mojarra impl 确实没有提供任何实用方法来隐藏它。它只是停在这里。你必须自己写。

    至少,在你的 sn-p 中,第二个if 检查null 是多余的,因为它never 返回null。此外,同一行上的behaviors.keySet().contains(key) 也可以简化为behaviors.containsKey(key)。鉴于它永远不会返回 null,您也可以立即获取行为列表并对其进行空检查。

    最后用一些实用方法隐藏它。

    public static Set<String> getClientBehaviorRenderIds(UIComponent component, String behaviorName) {
        Set<String> clientBehaviorRenderIds = new HashSet<String>();
    
        if (component instanceof ClientBehaviorHolder) {
            List<ClientBehavior> clientBehaviors = ((ClientBehaviorHolder) component).getClientBehaviors().get(behaviorName);
    
            if (clientBehaviors != null) {
                for (ClientBehavior clientBehavior : clientBehaviors) {
                    if (clientBehavior instanceof AjaxBehavior) {
                        clientBehaviorRenderIds.addAll(((AjaxBehavior) clientBehavior).getRender());
                    }
                }
            }
        }
    
        return clientBehaviorRenderIds;
    }
    

    以便您可以按如下方式使用它:

    Set<String> renderIds = getClientBehaviorRenderIds(component, "valueChange");
    // ...
    

    如果是嵌套检查令人不安,您也可以进行反向检查(Mojarra 一般也是这样写的;深度if 嵌套确实是一种不好的做法):

    public static Set<String> getClientBehaviorRenderIds(UIComponent component, String behaviorName) {
        Set<String> clientBehaviorRenderIds = new HashSet<String>();
    
        if (!(component instanceof ClientBehaviorHolder)) {
            return clientBehaviorRenderIds;
        }
    
        List<ClientBehavior> clientBehaviors = ((ClientBehaviorHolder) component).getClientBehaviors().get(behaviorName);
    
        if (clientBehaviors == null) {
            return clientBehaviorRenderIds;
        }
    
        for (ClientBehavior clientBehavior : clientBehaviors) {
            if (clientBehavior instanceof AjaxBehavior) {
                clientBehaviorRenderIds.addAll(((AjaxBehavior) clientBehavior).getRender());
            }
        }
    
        return clientBehaviorRenderIds;
    }
    

    【讨论】:

    • 好的,我认为可能有一个实用方法,但我没有看到。感谢您的逆向检查;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    • 2012-02-08
    • 2014-02-06
    • 2015-01-02
    • 2010-10-29
    • 2013-07-30
    • 1970-01-01
    相关资源
    最近更新 更多