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>