JSF:如何将actionListener附加到以编程方式创建的组件?

Muh*_*edy 2 jsf

我必须动态创建一些commandLinks并附加一些动作监听器,所以我已经<h:panelGrid>在JSP页面上使用这些代码来添加commandLinks并将动作监听器分配给:

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

 List<MyClass> myList = getSomeList();

 for (MyClass myObj : myList){
   FacesContext ctx = FacesContext.getCurrentContext();
   HtmlCommandLink cmdLink = (HtmlCommandLink) ctx.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);
 }
}
Run Code Online (Sandbox Code Playgroud)

但不幸的是,当我按下这个commandLinks时,抛出一个异常!如何在运行时添加组件事件侦听器?

(注意,上面的代码包含我刚才写的语法/编译错误).

Bal*_*usC 11

首先,你需要手动分配ID的任何动态创建UINamingContainer, UIInputUICommand组件.否则,JSF无法根据请求参数在组件树中找到它们,因为它与自动生成的ID不匹配.

因此,至少做到:

HtmlCommandLink link = new HtmlCommandLink();
link.setId("linkId");
// ...
Run Code Online (Sandbox Code Playgroud)

其次,你应该建立一个ActionListenerMethodExpression如下:

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

link.addActionListener(new MethodExpressionActionListener(methodExpression));
// ...
Run Code Online (Sandbox Code Playgroud)

...当然在后面的bean类中有以下方法#{bean}:

public void actionListener(ActionEvent event) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

以上所有动态内容基本上与以下原始JSF标记相同:

<h:commandLink id="linkId" actionListener="#{bean.actionListener}" />
Run Code Online (Sandbox Code Playgroud)