如何以编程方式添加AjaxBehavior与primefaces在UIComponent [英] How to programmatically add an AjaxBehavior to a UIComponent with primefaces
问题描述
由于我问<一href="http://stackoverflow.com/questions/15769371/a-programmatically-added-ajaxbehaviour-into-a-commandlink-doesnt-work">my最后一个问题(仍然没有答案)我继续寻找解决的办法,最后我发现的这个话题,我认为可以帮助实现我想要什么。
所以,我想,解决方案(这本身就是一个解决方法),但它仍然没有为我工作。
下面是code,这一切都只是一个测试针对此问题:
中的index.xhtml:
&LT; XML版本=1.0编码=ISO-8859-1&GT?;
&LT;!DOCTYPE HTML&GT;
&LT; HTML的xmlns =http://www.w3.org/1999/xhtml
的xmlns:H =http://java.sun.com/jsf/html
的xmlns:F =http://java.sun.com/jsf/core
的xmlns:P =http://primefaces.org/ui
的xmlns:UI =http://java.sun.com/jsf/facelets
的xmlns:C =http://java.sun.com/jsp/jstl/core&GT;
&LT; H:头&GT;
&LT; META HTTP-当量=Content-Type的CONTENT =text / html的;字符集= ISO-8859-1/&GT;
&LT;冠军&GT;达因添加谱曲测试&LT; /标题&GT;
&LT; / H:头&GT;
&LT;身体GT;
&LT; H:表格ID =Form1的&GT;
&LT;! - 这一次,第一次commandLink是clisked它会产生它下面另一个commandlink - &GT;
&LT; H:commandLink值=cliick我&GT;
&LT; F:Ajax事件=点击监听器=#{myBean.firstcmdLinkListenerHandler}/&GT;
&LT; / H:commandLink&GT;
&LT; /小时:形式GT;
&LT; /身体GT;
&LT; / HTML&GT;
管理bean:MyBean.java
包mybeans;
进口javax.el.Ex pressionFactory;
进口javax.el.MethodEx pression;
进口javax.faces.application.Application;
进口javax.faces.bean.ManagedBean;
进口javax.faces.bean.SessionScoped;
进口javax.faces.component.UIComponent;
进口javax.faces.component.html.HtmlCommandLink;
进口javax.faces.context.FacesContext;
进口javax.faces.event.AjaxBehaviorEvent;
进口javax.faces.event.BehaviorEvent;
进口org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl;
进口org.primefaces.context.RequestContext;
@ManagedBean
@SessionScoped
公共类MyBean {
公共无效handleClose(AjaxBehaviorEvent安倍晋三){
的System.out.println(!!! - &GT;&GT;&GT;&GT;&GT;阿贾克斯行为作品!!!!!);
}
公共无效reLoadCityList(BehaviorEvent事件){
的System.out.println(!!! - &GT;&GT;&GT;&GT;&gt;在reLoadCityList方法效果!!!!!);
}
公共无效firstcmdLinkListenerHandler(AjaxBehaviorEvent安倍晋三){
的System.out.println(firstcmdLinkListenerHandleris跑!);
FacesContext的FC = FacesContext.getCurrentInstance();
应用程序= fc.getApplication();
防爆pressionFactory EF = fc.getApplication()GETEX pressionFactory()。
UIComponent Form1中= fc.getViewRoot()findComponent(窗口1)。
如果(Form1中!= NULL){
//创建commandLink
HtmlCommandLink mynewcmdlink =(HtmlCommandLink)application.createComponent(HtmlCommandLink.COMPONENT_TYPE);
mynewcmdlink.setId(mynewcmdlink);
mynewcmdlink.setValue(clickme2 !!);
MyAjaxBehavior pajax =新MyAjaxBehavior();
类[] =杆新类[1];
票面[0] = BehaviorEvent.class;
//票面[0] = AjaxBehaviorEvent.class; (*)
//pajax.setListener(myCreateMetEx pression(reLoadCityList,真实,//void.class,PAR));
//我试图与这两个AjaxBehaviorEvent和BehaviorEvent如(*)
// MethodEx pression我= ef.createMethodEx pression(//fc.getELContext(),#{myBean.handleClose},void.class,标准杆);
MethodEx pression我= ef.createMethodEx pression(fc.getELContext(),#{myBean.reLoadCityList},void.class,标准杆);
//pajax.setListener(me); //我已经试过这一点,但它不是sucesseful
pajax.addAjaxBehaviorListener(新AjaxBehaviorListenerImpl(我));
pajax.setProcess(@this);
mynewcmdlink.addClientBehavior(变,pajax);
//添加thecommanLink到窗体
。form1.getChildren()加(mynewcmdlink);
//刷新的形式看到添加的commandLink:
RequestContext的背景下= RequestContext.getCurrentInstance();
context.update(窗口1);
context.update(form1的:富);
}其他
的System.out.println(form1的为空!);
}
和用作primefaces论坛文章的变通方法MyAjaxBehavior.java:
包mybeans;
进口的java.util.HashMap;
进口javax.el.ELContext;
进口javax.el.MethodEx pression;
进口javax.faces.component.UIComponentBase;
进口javax.faces.context.FacesContext;
进口javax.faces.event.AbortProcessingException;
进口javax.faces.event.BehaviorEvent;
进口org.primefaces.component.behavior.ajax.AjaxBehavior;
公共类MyAjaxBehavior扩展AjaxBehavior {
@覆盖
公共对象saveState和(FacesContext的上下文){
HashMap的&LT;字符串,对象&gt;地图;
图=新的HashMap&LT;字符串,对象&gt;();
map.put(更新,getUpdate());
map.put(过程,getProcess());
map.put(的onComplete,getOncomplete());
map.put(的onerror,getOnerror());
map.put(的onSuccess,getOnsuccess());
map.put(的OnStart,getOnstart());
map.put(监听器,getListener());
如果(initialStateMarked())
返回null;
返回UIComponentBase.saveAttachedState(背景下,地图);
}
@燮pressWarnings(未登记)
@覆盖
公共无效restoreState(FacesContext的上下文,对象状态){
如果(状态!= NULL){
HashMap的&LT;字符串,对象&gt;地图;
地图=(HashMap的&LT;字符串,对象&gt;)UIComponentBase
.restoreAttachedState(背景下,国家);
setUpdate((字符串)map.get(更新));
setProcess((字符串)map.get(过程));
setOncomplete((字符串)map.get(的onComplete));
setOnerror((字符串)map.get(onError的));
setOnsuccess((字符串)map.get(的onSuccess));
setOnstart((字符串)map.get(的OnStart));
使用setListener((MethodEx pression)map.get(监听器));
}
}
@覆盖
公共无效广播(BehaviorEvent事件)抛出AbortProcessingException {
ELContext eLContext = FacesContext.getCurrentInstance()getELContext()。
//向后兼容实现监听器调用
如果(getListener()!= NULL){
尝试 {
。getListener()调用(eLContext,新的对象[] {事件});
}赶上(抛出:IllegalArgumentException例外){
。getListener()调用(eLContext,新的对象[0]);
}
}
}
}
做这样的事
面板TP =新面板();
FacesContext的FC = FacesContext.getCurrentInstance();
防爆pressionFactory EF = fc.getApplication()GETEX pressionFactory()。
MethodEx pression我= ef.createMethodEx pression(fc.getELContext(),#{myView.closeIt},空,新的类&LT;&GT; [] {BehaviorEvent.class});
AjaxBehavior ajaxBehavior =(AjaxBehavior)fc.getApplication()createBehavior(AjaxBehavior.BEHAVIOR_ID)。
ajaxBehavior.setProcess(@本);
ajaxBehavior.addAjaxBehaviorListener(新AjaxBehaviorListenerImpl(我,我));
tp.addClientBehavior(关闭,ajaxBehavior);
。component.getChildren()加(TP);
myView.closeIt()的
公共无效closeIt(CE的closeEvent){
面板P =(面板)ce.getComponent();
的System.out.println(你什么都想要);
}
Since i've asked my last question (which still unanswered) i continued searching for a solution and lastly i found this topic which i think can help achieve what i want.
So , i tried that solution (which itself is a workaround) but it still didn't work for me.
Here is the code, it s all just a test for this issue :
the index.xhtml :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>dyn add comps test </title>
</h:head>
<body>
<h:form id="form1">
<!-- once this first commandLink is clisked it will generate another commandlink below it -->
<h:commandLink value="cliick me">
<f:ajax event="click" listener="#{myBean.firstcmdLinkListenerHandler}"/>
</h:commandLink>
</h:form>
</body>
</html>
The managed Bean : MyBean.java
package mybeans;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.faces.application.Application;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.BehaviorEvent;
import org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl;
import org.primefaces.context.RequestContext;
@ManagedBean
@SessionScoped
public class MyBean {
public void handleClose(AjaxBehaviorEvent abe){
System.out.println("!!!-->>>>> the Ajax Behaviour Works !!!!! ");
}
public void reLoadCityList( BehaviorEvent event ){
System.out.println("!!!-->>>>> the reLoadCityList method Works !!!!! ");
}
public void firstcmdLinkListenerHandler(AjaxBehaviorEvent abe){
System.out.println("firstcmdLinkListenerHandleris running ! ");
FacesContext fc = FacesContext.getCurrentInstance();
Application application = fc.getApplication();
ExpressionFactory ef = fc.getApplication().getExpressionFactory();
UIComponent form1 = fc.getViewRoot().findComponent("form1");
if(form1!=null){
//Creating the commandLink
HtmlCommandLink mynewcmdlink = (HtmlCommandLink)application.createComponent(HtmlCommandLink.COMPONENT_TYPE);
mynewcmdlink.setId("mynewcmdlink");
mynewcmdlink.setValue("clickme2!!");
MyAjaxBehavior pajax = new MyAjaxBehavior();
Class[] par = new Class[1];
par[0] = BehaviorEvent.class;
//par[0] = AjaxBehaviorEvent.class; (*)
//pajax.setListener( myCreateMetExpression( "reLoadCityList", true, //void.class, par ) );
//i tried with both AjaxBehaviorEvent and BehaviorEvent as in (*)
//MethodExpression me = ef.createMethodExpression( //fc.getELContext(), "#{myBean.handleClose}", void.class, par);
MethodExpression me = ef.createMethodExpression( fc.getELContext(), "#{myBean.reLoadCityList}", void.class, par);
//pajax.setListener(me); //i've tried with this too but it wasn't sucesseful
pajax.addAjaxBehaviorListener( new AjaxBehaviorListenerImpl( me ) );
pajax.setProcess( "@this" );
mynewcmdlink.addClientBehavior( "change", pajax );
//adding thecommanLink to the form
form1.getChildren().add(mynewcmdlink);
//Refreshing the form to see the added commandLink :
RequestContext context = RequestContext.getCurrentInstance();
context.update("form1");
context.update("form1:foo");
}else
System.out.println("form1 is null!!");
}
and the MyAjaxBehavior.java used as the workaround in the primefaces forum article:
package mybeans;
import java.util.HashMap;
import javax.el.ELContext;
import javax.el.MethodExpression;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.BehaviorEvent;
import org.primefaces.component.behavior.ajax.AjaxBehavior;
public class MyAjaxBehavior extends AjaxBehavior {
@Override
public Object saveState(FacesContext context) {
HashMap<String, Object> map;
map = new HashMap<String, Object>();
map.put("update", getUpdate());
map.put("process", getProcess());
map.put("oncomplete", getOncomplete());
map.put("onerror", getOnerror());
map.put("onsuccess", getOnsuccess());
map.put("onstart", getOnstart());
map.put("listener", getListener());
if (initialStateMarked())
return null;
return UIComponentBase.saveAttachedState(context, map);
}
@SuppressWarnings("unchecked")
@Override
public void restoreState(FacesContext context, Object state) {
if (state != null) {
HashMap<String, Object> map;
map = (HashMap<String, Object>) UIComponentBase
.restoreAttachedState(context, state);
setUpdate((String) map.get("update"));
setProcess((String) map.get("process"));
setOncomplete((String) map.get("oncomplete"));
setOnerror((String) map.get("onerror"));
setOnsuccess((String) map.get("onsuccess"));
setOnstart((String) map.get("onstart"));
setListener((MethodExpression) map.get("listener"));
}
}
@Override
public void broadcast(BehaviorEvent event) throws AbortProcessingException {
ELContext eLContext = FacesContext.getCurrentInstance().getELContext();
// Backward compatible implementation of listener invocation
if (getListener() != null) {
try {
getListener().invoke(eLContext, new Object[] { event });
} catch (IllegalArgumentException exception) {
getListener().invoke(eLContext, new Object[0]);
}
}
}
}
Do something like this
Panel tp = new Panel();
FacesContext fc = FacesContext.getCurrentInstance();
ExpressionFactory ef = fc.getApplication().getExpressionFactory();
MethodExpression me = ef.createMethodExpression(fc.getELContext(), "#{myView.closeIt}", null, new Class<?>[]{BehaviorEvent.class});
AjaxBehavior ajaxBehavior = (AjaxBehavior) fc.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);
ajaxBehavior.setProcess("@this");
ajaxBehavior.addAjaxBehaviorListener(new AjaxBehaviorListenerImpl(me, me));
tp.addClientBehavior("close", ajaxBehavior);
component.getChildren().add(tp);
myView.closeIt()
public void closeIt(CloseEvent ce){
Panel p = (Panel) ce.getComponent();
System.out.println("Do what ever you want");
}
这篇关于如何以编程方式添加AjaxBehavior与primefaces在UIComponent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!