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.
精彩评论