如何以编程方式将AjaxBehavior添加到具有primefaces的UIComponent

时间:2013-04-04 10:44:28

标签: ajax jsf-2 primefaces

因为我已经问my last question(仍然没有答案)我继续寻找解决方案,最后我发现this topic我认为可以帮助实现我想要的目标。

所以,我试过这个解决方案(这本身就是一种解决方法),但它仍然不适用于我。

以下是代码,这只是对此问题的测试:

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>

托管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!!");

}

和MyAjaxBehavior.java用作primefaces论坛文章中的变通方法:

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]);
            }
        }
    }

}

1 个答案:

答案 0 :(得分:6)

做这样的事情

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");
}