JSF自定义组件:如何获取<f:ajax> </f:ajax>的属性

时间:2011-09-01 09:09:20

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

我为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>

如何在渲染器中获取render-attribute的值?我只需要值,不应该写入我的组件(像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());
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

你究竟对此不满意吗?太冗长了?嗯,确实没有JSF API提供的实用方法,也没有Mojarra impl提供的实用方法。它就在这里停下来。你自己写吧。

至少,在您的代码段中,对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;
}