Pregunta

Hay un par de cosas que me cuesta entender con respecto al desarrollo de componentes personalizados en JSF.A los efectos de estas preguntas, puede asumir que todos los controles personalizados utilizan enlaces de valores/expresiones (no enlaces literales), pero también me interesan las explicaciones sobre ellos.

  1. ¿Dónde configuro el valor para el enlace de valores?¿Se supone que esto sucede en la decodificación?¿O debería decodificar hacer algo más y luego establecer el valor en encodeBegin?
  2. Leer del enlace de valor: ¿Cuándo leo los datos del enlace de valor vs.¿Leerlo del valor enviado y ponerlo en el enlace de valor?
  3. ¿Cuándo se llama a los oyentes de acción en los formularios en relación con todo esto?Todas las páginas del ciclo de vida de JSF mencionan eventos que ocurren en varios pasos, pero no me queda completamente claro cuándo se llama a un simple oyente de un botón de comando.

He probado algunas combinaciones, pero siempre termino con errores difíciles de encontrar que creo que provienen de malentendidos básicos del ciclo de vida del evento.

¿Fue útil?

Solución

Hay un diagrama bastante bueno en el especificación JSF que muestra el ciclo de vida de la solicitud, esencial para comprender este tema.

Los pasos son:

  • Restaurar vista.Se reconstruye el árbol UIComponent.
  • Aplicar valores de solicitud.Los componentes editables deben implementar EditableValueHolder.Esta fase recorre el árbol de componentes y llama al procesoDecodifica métodos.Si el componente no es algo complejo como UIData, no hará mucho excepto llamarlo propio descodificar método.El descodificar El método no hace mucho excepto encontrar su renderizador e invoca su descodificar método, haciéndose pasar por un argumento.Es trabajo del renderizador obtener cualquier valor enviado y configurarlo mediante establecerValorEnviado.
  • Validaciones de procesos.Esta fase llama procesoValidadores que llamará validar.El validar El método toma el valor enviado, lo convierte con cualquier convertidor, lo valida con cualquier validador y (suponiendo que los datos pasen esas pruebas) llama valor ajustado.Esto almacenará el valor como una variable local.Si bien esta variable local no es nula, se devolverá y no el valor del enlace de valor para cualquier llamada a obtenerValor.
  • Actualizar valores del modelo.Esta fase llama procesoActualizaciones.En un componente de entrada, esto llamará actualizarModelo que obtendrá el ValorExpresión e invocarlo para establecer el valor en el modelo.
  • Invocar aplicación.Aquí se invocarán detectores de eventos de botones, etc. (al igual que la navegación, si la memoria no me falla).
  • Renderizar respuesta.El árbol se representa a través de los renderizadores y se guarda el estado.
  • Si alguna de estas fases falla (p. ej.un valor no es válido), el ciclo de vida salta a Representar respuesta.
  • Se pueden activar varios eventos después de la mayoría de estas fases, invocando a los oyentes según corresponda (como los oyentes de cambio de valor después de las validaciones de procesos).

Esta es una versión algo simplificada de los hechos.Consulte las especificaciones para obtener más detalles.

Me preguntaría por qué estás escribiendo tu propio UIComponent.Esta no es una tarea trivial y se requiere un conocimiento profundo de la arquitectura JSF para hacerlo bien.Si necesita un control personalizado, es mejor crear un control concreto que extienda un UIComponent existente (como lo hace HtmlInputText) con un renderizador equivalente.

Si la contaminación no es un problema, existe una implementación JSF de código abierto en forma de Apache MyFaces.

Otros consejos

Oyentes de acción, como por ejemplo para un Botón de comando, son llamados durante el Invocar aplicación fase, que es la última fase antes de la final Renderizar respuesta fase.Esto se muestra en El ciclo de vida de JSF: figura 1.

Es el único marco que he usado donde la creación de componentes es un proceso intrincado profundo como este.Ninguno de los otros marcos web (ya sea en el mundo .NET o no) hace que esto sea tan doloroso, lo cual es completamente inexplicable para mí.

Algunas de las decisiones de diseño detrás de JSF comienzan a tener un poco más de sentido cuando se consideran los objetivos.JSF fue diseñado para ser equipado con herramientas: expone muchos metadatos para IDE.JSF no es un framework web, es un MVP framework que se puede utilizar como framework web.JSF es altamente extensible y configurable: puede reemplazar el 90% de la implementación por aplicación.

La mayoría de estas cosas simplemente complican tu trabajo si todo lo que quieres hacer es introducir un control HTML adicional.

El componente es una composición de varios componentes básicos de entrada (y otros), por cierto.

Supongo que los fragmentos de página basados ​​en herramientas/incluidos JSP no cumplen con sus requisitos.

Consideraría usar tu UIComponentELTag.createComponent para crear un control compuesto con una base UIPanel y crear todos sus hijos a partir de implementaciones existentes.(Supongo que estás usando JSP/taglibs y haciendo algunas otras conjeturas). Probablemente quieras un renderizador personalizado si ninguno de los renderizadores UIPanel existentes hizo el trabajo, pero los renderizadores son fáciles.

El mejor artículo que he encontrado es Escritura de componentes Jsf, en cuanto a 2, ¿dónde leo el valor para un valor de enlace en su componente? Tiene un obtenedor que se ve así


public String getBar() {  
     if (null != this.bar) {  
         return this.bar ;  
     }  
     ValueBinding _vb = getValueBinding("bar");  
     return (_vb != null) ? (bar) _vb.getValue(getFacesContext()) : null;  
}
  

¿Cómo llegó esto a getValueBinding?En el método setProperties de su clase de etiqueta

  if (bar!= null) {  
         if (isValueReference(bar)) {  
             ValueBinding vb = Util.getValueBinding(bar);  
             foo.setValueBinding("bar", vb);  
         } else {  
             throw new IllegalStateException("The value for 'bar' must be a ValueBinding.");  
         }  
     }  
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top