2010-09-14 113 views
13

Algunos antecedentes: Estoy creando un componente JSF personalizado. El componente es básicamente un editor de texto y debe tener un botón "Guardar" para guardar la cadena de contenido del editor. Como estoy usando la biblioteca CodeMirror, necesito buscar el contenido (cadena) del editor con javascript y enviar eso al servidor. Por lo tanto, en este caso no puedo usar la invocación JS basada en XML como f:ajax.JSF 2.0 AJAX: llame a un método de bean desde javascript con jsf.ajax.request (o de alguna otra manera)

La pregunta: Estaba planeando enviar la cadena con jsf.ajax.request, pero no admite directamente métodos de llamada en beans. ¿Cómo puedo invocar un método en un bean con JSF en modo AJAX?

Hay al menos dos maneras de evitar esto:

  • Incluir una forma oculta a la página con InputField oculto. Actualiza ese campo de entrada desde javascript y luego llama a jsf.ajax.request para publicar ese formulario. Las acciones personalizadas pueden invocarse en el getter o setter de la propiedad si es necesario.
  • Realice la solicitud con raw XMLHttpRequest (o tal vez con la ayuda de alguna otra biblioteca JS). Crea un servlet y llámalo.

Ambas formas son torpes y esta última también se sale del alcance de JSF.

¿Echo de menos algo? ¿Cómo haces esto?

Hay un quite similar question, pero las respuestas dadas solo se refieren a las invocaciones AJAX basadas en XML. También hay another similar question, pero eso también se refiere a llamadas AJAX basadas en XML.

+0

¿Cómo exactamente lo estás construyendo? Como 'UIComponent' o como' 'o' '? – BalusC

+0

Este está construido simplemente sobre 'ui: composition'. Básicamente tengo un 'textarea' allí, que inicializo con la invocación de JS dentro del elemento' script'. También tengo un 'commandButton' que debería funcionar como el botón Guardar.¿Por qué importa si uso componentes compuestos o UIComponents? –

+0

Con 'UIComponent' puede extender' UIInput' y JSF se ocupará de actualizar los valores del modelo. Pero después de pensar una vez más, eso es, por supuesto, complicado cuando se trata de un editor basado en HTML/CSS/JS de terceros. ¿Has considerado un componente de JSF completo? P.ej. [PrimeFaces 'p: editor'] (http://www.primefaces.org/showcase/ui/editor.jsf). – BalusC

Respuesta

15

No he podido encontrar la manera de llamar a los granos de direcly con javascript, pero aquí es un truco por ahí llamando f: ajax-declaración de javascript:

1) Crear un formulario oculto con campos para todos los datos que quieres enviar al servidor Incluir una h: commandButton así:

<h:form id="hiddenForm" style="display: none;"> 
    <h:inputHidden id="someData" value="#{someBean.someData}" /> 
    <h:commandButton id="invisibleClickTarget"> 
     <f:ajax execute="@form" listener="#{someBean.myCoolActionOnServer()}" /> 
    </h:commandButton> 
</h:form> 

Como de costumbre, listener atributo, #{someBean.myCoolActionOnServer()} en este caso, se refiere al método que desea ejecutar en el servidor.

2) En alguna otra onclick utilizar el botón para llamar a su Javascript especial y haga clic en el botón de disparo a través de JavaScript:

<h:commandButton value="Click me" onclick="populateTheForm('hiddenForm'); document.getElementById('hiddenForm:invisibleClickTarget').click(); return false;" /> 

populateTheForm() realidad debe llenar los datos en los campos de hiddenForm.

Esta es una simplificación de mi caso, pero debería funcionar. Sin embargo, aún estoy buscando un enfoque más conventiente.

+5

Como alternativa, también puede dejarlo el '' y use '' dentro de '' que se ejecuta en el evento 'change'. Eso es menos código. – BalusC

+0

Sí, eso debería funcionar si el usuario quiere transferir solo un campo (bueno, en este caso lo hago). Con varios campos dentro del formulario, supongo que podría desencadenar un comportamiento no deseado, con el lanzamiento de la llamada AJAX antes de que el resto de los campos pueda actualizarse. –

+0

... a menos que uno ponga '' f: ajax' para el campo que se actualizó al último. Sí, eso haría el truco. Gracias por sus sugerencias una vez más, BalusC. –

1

Realicé esta tarea varias veces. No necesitas múltiples campos ocultos. Puede usar solo un campo oculto, convertir todos los valores de entrada al objeto JSON a través de JSON.stringify y establecerlo en este campo. Del lado del servidor: deserialice el objeto JSON (hay muchas librerías Java para eso) en una clase Java. Eso es todo.

+1

Eso es bueno saber, aunque ¿de qué te beneficias? Al tener múltiples campos JSF realiza conversiones/validaciones automáticamente, su código se tipea de manera más estática (aunque el enfoque sigue siendo desagradable). ¿Te importa abrir un poco? –

Cuestiones relacionadas