Jsf 我可以让一个panelGroup链接到一个没有f:ajax侦听器的侦听器吗?

Jsf 我可以让一个panelGroup链接到一个没有f:ajax侦听器的侦听器吗?,jsf,jsf-2,Jsf,Jsf 2,我将f:ajax标记替换为一个自制的解决方案,该解决方案不放入内联脚本。它适用于操作按钮。但是,我无法使它适用于面板组上的侦听器。原因是没有指定ajax请求产生的bean目标方法应该是什么。换句话说,通过命令按钮我可以在操作中指定目标bean方法,但是面板组没有这样的属性;因为我不想使用f:ajax监听器,所以我想替换它 <h:commandButton data-widget="jsfajax" value="ajax" action="#{someAction}"/> $(do

我将
f:ajax
标记替换为一个自制的解决方案,该解决方案不放入内联脚本。它适用于
操作按钮
。但是,我无法使它适用于
面板组
上的侦听器。原因是没有指定ajax请求产生的bean目标方法应该是什么。换句话说,通过
命令按钮
我可以在
操作
中指定目标bean方法,但是
面板组
没有这样的属性;因为我不想使用
f:ajax监听器
,所以我想替换它

 <h:commandButton data-widget="jsfajax" value="ajax" action="#{someAction}"/>
$(document).ready(function(){   
    (function(widgets){
        document.body.addEventListener("click", function(e) {
               var w = e.target.getAttribute("data-widget");
               if(w){
                   e.preventDefault();
                   widgets[w](e.target);
               }
            });
    })(new Widgets);
});
function Widgets(){
    this.jsfajax =  function jsfajax(elem){ 
            if(elem.id == ""){
            elem.id = elem.name;
        }
       mojarra.ab(elem,"click",'action','@form',0);  
     }
}

$(文档).ready(函数(){
(功能(小部件){
document.body.addEventListener(“单击”,函数(e){
var w=e.target.getAttribute(“数据小部件”);
如果(w){
e、 预防默认值();
小部件[w](即目标);
}
});
})(新部件);
});
函数Widgets(){
this.jsfajax=函数jsfajax(elem){
如果(元素id==“”){
elem.id=elem.name;
}
ab(elem,“click”,“action”,“form”,0);
}
}
这很有效

但这显然没有(它有,但它没有调用任何东西):


点击这里
但这确实:

 <h:panelGroup>
    <f:ajax event="click" listener="#{someAction}"/>
    Click here
 </h:panelGroup>

点击这里
这两个
panelGroup
都会产生相同的HTML输出,因此我假设是jsf容器“记住”了对该panelGroup的点击链接到
{someAction}

我想做的是在不使用
f:ajax侦听器的情况下重新创建该链接。目前,我不得不使用一个隐藏的命令按钮,这是不太优雅。

因此,我不知道,可能是一个复合组件panelGroup可以保存“操作链接”。

您想要实现的功能只能在
UICommand
组件上实现,而不能在
ClientBehaviorHolder
组件上实现。一种解决方案是创建一个扩展
HtmlCommandLink
的自定义组件,它呈现
而不是


我很好奇你为什么想要这个?只是为了防止内联js?当您使用ajax进行更新时,需要再次运行所有这些。内联js的优点大于缺点吗?@Kukeltje我不需要在更新后再次运行它,单击事件被委托给文档。我希望这样做,因为我计划禁止内联js。使用内容安全策略标头。老实说,我更喜欢这样。在这种情况下,一个小组真的很烦人。@Kukeltje我已经打开了一个赏金,如果你有其他信息,欢迎:)@BalusC抱歉,我复制粘贴了整个工作代码,然后删除了我认为不必要的内容。我现在就做。我认为这是正确的。我向上投了票,因为我担心你会认为这是我lol,很抱歉花了我的时间接受它。没问题,慢慢来。我不希望自定义渲染器是内置功能,所以这比我希望的要好。我做了一个自定义渲染器,扩展了
GroupRenderer
,在
encodeBegins
中,我得到了
clientBehaviors
。然后,如果
click
位于地图的关键帧中,我将添加该属性。这将在html中呈现一个
数据小部件
attr,而该小部件又可以触发ajax请求。我还没把它传到听者那里呢,也许你有一个指针?从一大早开始,我花了一些时间进一步阅读,但我想我已经到达了目的地,但我很累,所以我会在之后完成。我会在完成后将它注册,因为您说过它可能很流行,请将您的
mojarra.ab
调用与默认调用进行比较。你当前问题中的那个确实不适用于
。基本上,你应该调用
mojarra.ab(event.target,event,“click”,0,0)
。对于未来的悬赏问题,一个提示是:只需标记接受的答案,让悬赏过期。当问题上升到悬赏的最后几天,通过悬赏列表的用户的兴趣/同情投票机会增加,因此你几乎可以赢回花在悬赏上的声誉。
 <h:panelGroup>
    <f:ajax event="click" listener="#{someAction}"/>
    Click here
 </h:panelGroup>
<render-kit>
    <renderer>
        <component-family>javax.faces.Panel</component-family>
        <renderer-type>javax.faces.Group</renderer-type>
        <renderer-class>com.example.YourPanelGroupRenderer</renderer-class>
    </renderer>
</render-kit>
public class NoInlineScriptRenderKitFactory extends RenderKitFactory {

    private RenderKitFactory wrapped;

    public NoInlineScriptRenderKitFactory(RenderKitFactory wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public void addRenderKit(String renderKitId, RenderKit renderKit) {
        wrapped.addRenderKit(renderKitId, renderKit);
    }

    @Override
    public RenderKit getRenderKit(FacesContext context, String renderKitId) {
        RenderKit renderKit = wrapped.getRenderKit(context, renderKitId);
        return (HTML_BASIC_RENDER_KIT.equals(renderKitId)) ? new NoInlineScriptRenderKit(renderKit) : renderKit;
    }

    @Override
    public Iterator<String> getRenderKitIds() {
        return wrapped.getRenderKitIds();
    }

}
public class NoInlineScriptRenderKit extends RenderKitWrapper {

    private RenderKit wrapped;

    public NoInlineScriptRenderKit(RenderKit wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public ResponseWriter createResponseWriter(Writer writer, String contentTypeList, String characterEncoding) {
        return new NoInlineScriptResponseWriter(super.createResponseWriter(writer, contentTypeList, characterEncoding));
    }

    @Override
    public RenderKit getWrapped() {
        return wrapped;
    }

}
public class NoInlineScriptResponseWriter extends ResponseWriterWrapper {

    private ResponseWriter wrapped;

    public NoInlineScriptResponseWriter(ResponseWriter wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public ResponseWriter cloneWithWriter(Writer writer) {
        return new NoInlineScriptResponseWriter(super.cloneWithWriter(writer));
    }

    @Override
    public void writeAttribute(String name, Object value, String property) throws IOException {
        if (name.startsWith("on")) {
            if (value != null && value.toString().startsWith("mojarra.ab(")) {
                super.writeAttribute("data-widget", "jsfajax", property);
            }
        }
        else {
            super.writeAttribute(name, value, property);
        }
    }

    @Override
    public ResponseWriter getWrapped() {
        return wrapped;
    }

}
<factory>
    <render-kit-factory>com.example.NoInlineScriptRenderKitFactory</render-kit-factory>
</factory>