Tuesday, February 9, 2010

Using action bindings in facelets template components

When creating Facelets template components, you might face difficulties when trying to pass action bindings as component or template parameters. The problem is that the method binding gets evaluated at the place it is used, so if you write:

  <my:actionComponent action="#{backing.method}"/>

the method is invoked and the result value will be available for named 'action' inside the template. To change this behaviour, I created a method in a backing named 'ELEvaluator':

 public void evaluateMethodBinding(String el) {
  ValueExpression ve = FacesContext.getCurrentInstance().getApplication().getExpressionFactory()
   .createValueExpression(FacesContext.getCurrentInstance().getELContext(), "#{" + el + "}", Object.class);
  ve.getValue(FacesContext.getCurrentInstance().getELContext());
 }

Inside the template component I use:

    action="#{ELEvaluator.evaluateMethodBinding(action)}" 

And when passing the action parameter, I have to pass a normal String, without the '#{}' stuff:

 <my:actionComponent [...] action="backing.method(params)"/>

See also: http://seamframework.org/Community/FaceletsParamForActionMethod

No comments:

Post a Comment