2009-12-21 50 views
8

Antes de continuar, consulte este formulario JSF question¿Cómo recupero un valor de componente JSF utilizando EL?

Es se muestra de nuevo de la siguiente manera:

<f:view> 
    <h:form> 
     <div> 
      <label>Id</label> 
      <input type="text" name="accountId"/> 
     </div> 
     <div> 
      <label>Amount</label> 
      <input type="text" name="amount"/> 
     </div> 
     <h:commandButton value="Withdraw" action="#{accountService.withdraw(param.accountId, param.amount)}"/> 
    </h:form> 
</f:view> 

Tenga en cuenta que he utilizado en lugar de <input type="text" name="amount"><h:inputText id="amount">. Para recuperar su valor utilizando Seam EL resolver, uso param.amount.

Ocurre que si uso <input type="text" y algo va mal en el lado del servidor, tengo que volver a mostrar la página. Por lo tanto, su valor enviado no se recupera porque es un código html simple. Por eso, necesito usar un componente JSF <h:inputText en su lugar.

Entonces la pregunta es: ¿Cómo recupero un valor de componente <h:inputText JSF utilizando Expression Language?

+0

Para empezar, su pregunta era bastante confusa. Parece que la historia de Seam es completamente irrelevante aquí. En el futuro, publique el código JSF que ** en realidad ** tiene y diga qué es exactamente lo que quiere hacer con ** su ** código. – BalusC

+0

Esto tampoco tiene sentido. En JSP/Servlet simple, podría haber usado '' para eso. – BalusC

+0

Recomiendo encarecidamente obtener un libro/tutorial JSF decente para comprender cómo funciona JSF "debajo de las capuchas". También aprender JSP/Servlet "plain vanilla" ayudaría mucho a entenderlo. Estás haciendo suposiciones y estás tratando de romper la ideología de JSF tomando todo su trabajo en tus propias manos. Lo siento si sueno duro, pero esa es la verdad. – BalusC

Respuesta

18

de la ID de cliente JSF se antepone por el ID cliend de padre UINamingContainer componentes (por ejemplo h:form, h:dataTable, f:subview). Si comprueba la fuente HTML generada en su navegador web (haga clic con el botón derecho, ver fuente), debería verlas. El id y el name de los elementos de entrada generados se anteponen con el id del formulario principal. Debe usar el mismo nombre que la clave en el mapa de parámetros. Como el carácter separador, el : de dos puntos, es un carácter "ilegal" en EL, debe usar la notación de llaves param['foo:bar'] para recuperarlos.

<f:view> 
    <h:form id="account"> 
     <div> 
      <label>Id</label> 
      <h:inputText id="id" /> 
     </div> 
     <div> 
      <label>Amount</label> 
      <h:inputText id="amount" /> 
     </div> 
     <h:commandButton value="Withdraw" 
      action="#{accountService.withdraw(param['account:id'], param['account:amount'])}"/> 
    </h:form> 
</f:view> 

Sin parámetros del método Seam-EL-como (que al parecer no quiere que el/la tienen), también se puede acceder a ellos en el mapa de solicitud de parámetros utilizando el ID de cliente de como claves:

public void withDraw() { 
    Map<String, String> map = FacesContext.getCurrentInstance().getRequestParameterMap(); 
    String id = map.get("account:id"); 
    String amount = map.get("account:amount"); 
    // ... 
} 

No hace falta decir que esto es desagradable. Simplemente hazlo de la manera normal JSF, vincula los valores con las propiedades de los beans.

Editar: según la pregunta final que ha editado:

Así que la pregunta es: ¿Cómo puedo recuperar un valor de componente JSF <h:inputText mediante el uso de lenguaje de expresión?

Esto ya está respondido antes. Use el nombre JSF generado como nombre de parámetro. Esto generalmente está en el patrón de formId:inputId donde formId es el id del componente principal UIForm y el inputId es el id del componente UIInput. Compruebe el resultado HTML generado para obtener el nombre exacto del campo generado <input type="text">. Para obtener el valor del parámetro, use la notación ortopédica ['name'], porque no puede usar los dos puntos : en EL como en ${param.formId:inputId}.

Así:

#{param['formId:inputId']} 
+0

Hm, ¿esta era su propia respuesta y se suponía que esto iba a funcionar? Bueno, solo puedo insinuar que verifique el resultado HTML generado para ver si los nombres son correctos y/o si están disponibles en el mapa de parámetros de solicitud. – BalusC

+0

Entonces, ¿está diciendo que * realmente * tiene una 'h: inputText' en su página JSF y no' '? De esta manera, debe darle (y el formulario principal) un 'id' y obtener el parámetro con la ID de cliente generada como clave. Voy a editar mi respuesta pronto. – BalusC

+0

Están en el mapa de parámetros de solicitud. Por ejemplo, ¿has depurado sus contenidos? 'System.out.println (requestParameterMap);' para que pueda verlos y los patrones? – BalusC

1

Los nombres de los parámetros/ids para inputText son encapsulados por el procesador de control y son, en última instancia, un detalle de implementación. En la práctica, usan el clientId. No debería ser necesario leerlos directamente desde el mapa de parámetros; utilice el enlace de valor para insertarlos en el modelo y leerlos desde allí.

Puede leer los valores directamente del componente utilizando EL vinculando el componente a un bean administrado. Por simplicidad, aquí está uno vinculado al ámbito de solicitud:

<!-- bind a UIComponent to the request map as "foo" --> 
<h:inputText binding="#{requestScope.foo}" /> 
<!-- read value from a UIComponent that implements ValueHolder --> 
#{requestScope.foo.value} 

Pero, por lo general, no hay ninguna ventaja a este sobre: ​​

<!-- bind a value to the request map as "foo" --> 
<h:inputText value="#{requestScope.foo}" /> 
<!-- read value from the request scope --> 
#{requestScope.foo} 

para no contaminar el mapa solicitud (que podría dar lugar a colisiones través vistas), use un bean administrado para namespace/encapsular sus valores en lugar de usar directamente el alcance de la solicitud.

+0

Good insigth, MCDowell. (+1) –

0

pesar de que puede recuperar el valor de componentes JSF a través de su identificador de cliente, hay algunas inconveniente de la siguiente manera:

  1. Según la respuesta de McDowell, El identificador de cliente es un detalle de implementación
  2. El identificador de cliente puede diferir de el identificador de componente cuando hay más de un contenedor de nombres en la jerarquía de control. (JSF en el libro Acción)

Así que si usted no quiere depender de identificador de cliente, usted puede implementar su propio ElResolver de la siguiente manera:

public class ComponentIdResolver extends ELResolver { 

    public Object getValue(ELContext context, Object base, Object property) { 
     if (base instanceof UIComponent && property instanceof String) { 
      UIComponent r = ((UIComponent) base).findComponent((String) property); 

      if (r != null) { 
       context.setPropertyResolved(true); 

       return r; 
      } 
     } 

     return null; 
    } 

} 

ahora puedo usar algo como (Observe retirar método)

<h:inputText id="accountId" /> 
<h:inputText id="amount" /> 
<h:commandButton value="Withdraw" action="#{accountService.withdraw(view.accountId.value, view.amount.value)}"/> 

vista es un objeto JSF implícita (similar a FacesContext.getCurrentInstance(). getViewRoot())

Entonces REG ister su ELResolver como se muestra a continuación (faces-config.xml)

<application> 
    <el-resolver>br.com.view.resolver.ComponentIdResolver</el-resolver> 
</application> 

Si quieres saber un buen conocimiento acerca de ElResolver ver Extending the Java EE Unified Expression Language with a Custom ELResolver

respecto,

Cuestiones relacionadas