Jim*_*ugh 20 java ajax listener composite-component jsf-2
我有一个JSF 2复合组件,它采用了一些Ajax行为.我想添加一个listener方法到<f:ajax>标签我复合组件内部,但listener方法应为提供<composite:attribute>的<composite:interface>.
<f:ajax>我的复合组件中的标签当前是硬编码到这样的监听器:
<f:ajax
event="valueChange"
execute="@this"
listener="#{controller.genericAjaxEventLogger}"
render="#{cc.attrs.ajaxRenderTargets}" />
Run Code Online (Sandbox Code Playgroud)
bean上的listener方法有这个签名:
public void genericAjaxEventLogger(AjaxBehaviorEvent event)
throws AbortProcessingException {
// implementation code...
}
Run Code Online (Sandbox Code Playgroud)
我希望复合组件是这样的,所以页面可以提供自己的事件方法,但我无法弄清楚接口的正确语法.
<f:ajax
event="valueChange"
execute="@this"
listener="#{cc.attrs.ajaxEventListener}"
render="#{cc.attrs.ajaxRenderTargets}" />
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
更新解决方案:
我采用了BalusC建议的方法,效果很好.相关的片段是:
复合组件中的接口声明
<composite:interface>
<composite:attribute
name="myattributeUpdatedEventListener"
method-signature="void listener()"
required="true" />
...
</composite:interface>
Run Code Online (Sandbox Code Playgroud)
我的复合组件中使用的Ajax标记
<f:ajax
event="valueChange"
execute="@this"
listener="#{cc.attrs.myattributeUpdatedEventListener}"
render="#{cc.attrs.ajaxRenderTargets}" />
Run Code Online (Sandbox Code Playgroud)
我在页面中使用复合组件的位置
<h:form>
<compcomp:myCompositeComponent
myattributeUpdatedEventListener="#{myBackingBean.updatedEventListenerXYZ}" />
</h:form>
Run Code Online (Sandbox Code Playgroud)
和我的支持bean上的方法
public void updatedEventListenerXYZ() {
// do something here...
}
Run Code Online (Sandbox Code Playgroud)
Bal*_*usC 24
如果你能摆脱这种AjaxBehaviorEvent说法,
public void genericAjaxEventLogger() {
// ...
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用
<cc:attribute name="ajaxEventListener" method-signature="void listener()" />
Run Code Online (Sandbox Code Playgroud)
如果参数是必需的(对于日志记录?),则需要重新指定属性,如下所示
<cc:attribute name="ajaxEventListener" method-signature="void listener(javax.faces.event.AjaxBehaviorEvent)" />
Run Code Online (Sandbox Code Playgroud)
但是,这在这里不能正常工作
<f:ajax listener="#{cc.attrs.ajaxEventListener}" />
Run Code Online (Sandbox Code Playgroud)
在GF 3.1 + Mojarra 2.1.1上:
SEVERE: javax.faces.FacesException: wrong number of arguments
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:89)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
at com.sun.faces.facelets.el.ContextualCompositeMethodExpression.invoke(ContextualCompositeMethodExpression.java:177)
at com.sun.faces.facelets.tag.TagAttributeImpl$AttributeLookupMethodExpression.invoke(TagAttributeImpl.java:450)
at com.sun.faces.facelets.tag.jsf.core.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxHandler.java:447)
at javax.faces.event.AjaxBehaviorEvent.processListener(AjaxBehaviorEvent.java:113)
at javax.faces.component.behavior.BehaviorBase.broadcast(BehaviorBase.java:102)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:760)
at javax.faces.component.UICommand.broadcast(UICommand.java:300)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
... 28 more
Run Code Online (Sandbox Code Playgroud)
我不确定这是不是一个bug.为此,我需要投入更多时间来naildown它.但是,它可以通过创建一个支持组件来解决,该组件MethodExpression从属性中获取并使用正确数量的参数进行调用.这是一个完整的启动示例:
<ui:component
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<cc:interface componentType="testCC">
<cc:attribute name="ajaxEventListener" method-signature="void listener(javax.faces.event.AjaxBehaviorEvent)" />
</cc:interface>
<cc:implementation>
<h:commandButton value="Submit">
<f:ajax listener="#{cc.ajaxEventListener}" />
</h:commandButton>
</cc:implementation>
</ui:component>
Run Code Online (Sandbox Code Playgroud)
同
package com.example;
import javax.el.MethodExpression;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
@FacesComponent(value="testCC")
public class TestCC extends UINamingContainer {
public void ajaxEventListener(AjaxBehaviorEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
MethodExpression ajaxEventListener = (MethodExpression) getAttributes().get("ajaxEventListener");
ajaxEventListener.invoke(context.getELContext(), new Object[] { event });
}
}
Run Code Online (Sandbox Code Playgroud)
无论如何,我相信支持组件为新方法打开了大门,以实现您想到的功能要求;)
| 归档时间: |
|
| 查看次数: |
29117 次 |
| 最近记录: |