2011-06-15 14 views
11

El título realmente lo dice todo. he hecho un intento que falló con el error:Pase de argumento a un atributo de acción de componente compuesto

Illegal attempt to pass arguments to a composite component lookup expression (i.e. cc.attrs.[identifier]).

Mi intento es el siguiente:

<composite:interface> 
    <composite:attribute name="removeFieldAction" method-signature="void action(java.lang.String)" /> 
</composite:interface> 
<composite:implementation> 
    <h:commandButton value="Remove" action="#{cc.attrs.removeFieldAction('SomeString')}"/> 
</composite:implementation> 

Cuál es la forma correcta de hacer esto?

Respuesta

29

Esto de hecho no va a funcionar. No puede pasar parámetros "extra" después de esa manera. El method-signature como ha declarado debe cumplirse en el lado donde se ha utilizado el componente compuesto. P.ej.

<my:button action="#{bean.remove('Somestring')}" /> 

La implementación componente compuesto solo debería tener este aspecto

<h:commandButton value="Remove" action="#{cc.attrs.removeFieldAction}" /> 

Si esto no es lo que quiere y que realmente quieren pasar por el lado componente compuesto, entonces lo que pueda piense en dos formas de pasar argumentos adicionales: usando <f:attribute> con un detector de acciones para pasarlo como un atributo de componente attidional, o <f:setPropertyActionListner> para permitir que JSF lo establezca como propiedad justo antes de invocar la acción. Pero ninguno de los dos está sin cambios en el componente compuesto. Debería solicitar al menos todo el bean como un atributo del componente compuesto.

Aquí hay un ejemplo con <f:setPropertyActionListener>. Esto establece la propiedad justo antes de invocar la acción.

<composite:interface> 
    <composite:attribute name="bean" type="java.lang.Object" /> 
    <composite:attribute name="action" type="java.lang.String" /> 
    <composite:attribute name="property" type="java.lang.String" /> 
</composite:interface> 
<composite:implementation> 
    <h:commandButton value="Remove" action="#{cc.attrs.bean[cc.attrs.action]}"> 
     <f:setPropertyActionListener target="#{cc.attrs.bean[cc.attrs.property]}" value="Somestring" /> 
    </h:commandButton> 
</composite:implementation> 

que es para ser utilizado como

<my:button bean="#{bean}" action="removeFieldAction" property="someString" /> 

Con el ejemplo anterior, el grano debe ser similar

public class Bean { 

    private String someString; 

    public void removeFieldAction() { 
     System.out.println(someString); // Somestring 
     // ... 
    } 

    // ... 
} 

Si se adhieren a una convención específica, puede incluso omitir la property atributo por completo.

+0

Tnx. La idea es que el componente compuesto crea una lista de campos con cada campo vinculado a un objeto en el bean. Una vez que se elimina un campo de la interfaz de usuario, se debe notificar al bean la ID del campo eliminado para que también se elimine del bean. Por lo tanto, el parámetro 'someString' es, de hecho, el UUID del campo eliminado. Estoy, en la práctica, tratando de lograr algo similar a un oyente de eventos con un argumento ... ¡Gracias por la solución! – Ben

+1

Hola BalusC. Muchas gracias por esta respuesta. Esto funciona en Mojarra pero parece que no funciona en MyFaces. Publiqué un número por separado aquí, ¿podrías echar un vistazo cuando tengas tiempo, por favor? http://stackoverflow.com/questions/17357593/passed-argument-to-method-inside-composite-component-does-not-work-on-myfaces Muchas gracias –

Cuestiones relacionadas