开发者

JSF: How to attach an actionListener to component created programatically?

开发者 https://www.devze.com 2022-12-18 01:50 出处:网络
I have to create some commandLinks dynamically and attach some action listener to it, So I\'ve put <h:panelGrid> on the JSP page and used such code to add the commandLinks and to assign action l

I have to create some commandLinks dynamically and attach some action listener to it, So I've put <h:panelGrid> on the JSP page and used such code to add the commandLinks and to assign action listeners to:

public ManagedBean(){
 List<UIComponenet> child = panelGrid.getChilderen();
 list.clear();

 List<MyClass> myList = getSomeList();

 for (MyClass myObj : myList){
   FacesContext ctx = FacesContext.getCurrentContext();
   HtmlCommandLink cmdLink = (HtmlCommandLink) c开发者_运维知识库tx.getApplication.createComponent(HtmlCommandLink.COMPONENT_TYPE);
   cmdLink.setValue(myObj.getName());
   cmdLink.setActionLinstner(new ActionListener(){
     public void processAction(ActionEvent event) throws AbortProcessingException{
       System.out.println (">>>>>>>>>>>>>>>>>I am HERE ");
     }
   });
   child.add(cmdLink);
 }
}

But unfortunately, when I press this commandLinks, an exception thrown! How can I add component event listeners at runtime?

(Note, the code above my contain syntax/compilation errors as I just wrote).


First, you need to manually assign ID to any dynamically created UINamingContainer, UIInput and UICommand components. Otherwise JSF can't locate them in the component tree based on the request parameters, because it wouldn't match the autogenerated ID's.

Thus, at least do:

HtmlCommandLink link = new HtmlCommandLink();
link.setId("linkId");
// ...

Second, you're supposed to create an ActionListener as MethodExpression as follows:

FacesContext context = FacesContext.getCurrentInstance();
MethodExpression methodExpression = context.getApplication().getExpressionFactory().createMethodExpression(
    context.getELContext(), "#{bean.actionListener}", null, new Class[] { ActionEvent.class });

link.addActionListener(new MethodExpressionActionListener(methodExpression));
// ...

...and of course have the following method in the backing bean class behind #{bean}:

public void actionListener(ActionEvent event) {
    // ...
}

All the above dynamic stuff basically does the same as the following raw JSF tag:

<h:commandLink id="linkId" actionListener="#{bean.actionListener}" />


I had the same problem. Transient components do not work with actionListeners. Do not call

FacesContext.getCurrentInstance().getViewRoot().setTransient(true); or component.setTransient(true);

As soon as I removed it, it was OK.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号