java - jsf tags
Componentes de JSF Lifecycle y Custom (6)
Hay un par de cosas que estoy teniendo dificultades para entender con respecto al desarrollo de componentes personalizados en JSF. A los fines de estas preguntas, puede suponer que todos los controles personalizados utilizan valores de enlace / expresiones (no enlaces de texto). Aunque con mucho gusto les recomendaré a aquellos que den buenas explicaciones sobre eso, ya que podría ser útil para otros (y para mí en el futuro).
- ¿Dónde configuro el valor para el enlace de valor? ¿Se supone que esto suceda en la decodificación? ¿O debería decodificar hacer otra cosa y luego tener el valor establecido en encodeBegin?
- Lea de la vinculación de valores: ¿cuándo leo datos del enlace de valor frente a leerlos de valor enviado y ponerlos en el enlace de valor?
- ¿Cuándo se llaman 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 resulta completamente claro cuando solo se está llamando a un simple oyente para un botón de comando
Intenté 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.
Es el único marco que he usado donde la creación de componentes es un proceso complejo como este. Ninguno de los otros marcos web (ya sea en el mundo de .net o no) lo hace 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 procesado: expone muchos metadatos para IDE. JSF no es un marco web; es un marco MVP que se puede usar como un marco web. JSF es altamente extensible y configurable: puede reemplazar el 90% de la implementación por aplicación.
La mayoría de estas cosas hacen que tu trabajo sea más complicado si lo único que quieres hacer es deslizarte en un control HTML adicional.
El componente es una composición de varios componentes de base de entrada (y otros), por cierto.
Supongo que los fragmentos de página basados en JSP-includes / tooling no cumplen con sus requisitos.
Consideraría usar su UIComponentELTag.createComponent para crear un control compuesto con una base UIPanel y crear todos sus elementos secundarios a partir de implementaciones existentes. (Supongo que está utilizando JSP / taglibs y haciendo algunas otras suposiciones). Probablemente desee un renderizador personalizado si ninguno de los renderizadores UIPanel existentes hiciera el trabajo, pero los renderizadores son fáciles.
@McDowell - Gracias por la información ... Pude averiguar la mayor parte de esto en la mañana leyendo el código MyFaces, pero ha agregado y aclarado una serie de detalles que son útiles.
Me pregunto por qué estás escribiendo tu propio UIComponent. Esta es una tarea no trivial y se requiere un profundo conocimiento de la arquitectura JSF para hacerlo bien.
Honestamente, he tenido problemas con el uso de JSF por exactamente esta razón. Es el único marco que he usado donde la creación de componentes es un proceso complejo como este. Ninguno de los otros marcos web (ya sea en el mundo de .net o no) lo hace tan doloroso, lo cual es completamente inexplicable para mí.
Me he quedado con JSF principalmente por la promesa de que 2.0 lo hará mucho menos doloroso. El componente es una composición de varios componentes de base de entrada (y otros), por cierto.
@McDowell:
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 procesado: expone muchos metadatos para IDE. JSF no es un marco web; es un marco MVP que se puede usar como un marco web. JSF es altamente extensible y configurable: puede reemplazar el 90% de la implementación por aplicación.
De eso, creo que la única parte con la que estoy de acuerdo es "un poco más de sentido". Los metadatos podrían haber sido expuestos de otras formas en JSF 1.2, y francamente, aún no he visto que un IDE haga un uso decente de él. ¿Por qué un IDE no puede darme una forma simple de construir un componente?
También he usado ASP.Net, y en comparación, JSF parece haber sido escrito por un grupo de astronautas de arquitectura dirigidos por un tipo como el diseñador original de Struts. Oh espera... :)
Hay un diagrama bastante bueno en la especificación JSF que muestra el ciclo de vida de la solicitud, esencial para entender esto.
Los pasos son:
- Restaurar vista . El árbol UIComponent se reconstruye.
- Aplicar valores de solicitud . Los componentes editables deben implementar EditableValueHolder. Esta fase recorre el árbol de componentes y llama a los métodos processDecodes . Si el componente no es algo complejo como un UIData, no hará mucho excepto llamar a su propio método de decodificación . El método de decodificación no hace mucho, excepto encontrar su representador e invoca su método de decodificación , pasando a sí mismo como un argumento. El trabajo del renderizador es obtener cualquier valor enviado y establecerlo a través de setSubmittedValue .
- Validación de procesos Esta fase llama a validadores de proceso que llamarán a validar . El método de validación toma el valor enviado, lo convierte con cualquier convertidor, lo valida con cualquier validador y (suponiendo que los datos pasen esas pruebas) llama a setValue . 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 getValue .
- Actualizar los valores del modelo . Esta fase llama processUpdates . En un componente de entrada, esto llamará a updateModel que obtendrá ValueExpression e invocarlo para establecer el valor en el modelo.
- Solicitud de invocación . Los oyentes de evento de botón y demás se invocarán aquí (al igual que la navegación si la memoria sirve).
- Renderizar respuesta . El árbol se representa a través de los renderizadores y el estado se guarda.
- Si alguna de estas fases falla (p. Ej., Un valor no es válido), el ciclo de vida salta a Respuesta de procesamiento.
- 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 valores después de las Validaciones de proceso).
Esta es una versión de eventos algo simplificada. Consulte la especificación para más detalles.
Me pregunto por qué estás escribiendo tu propio UIComponent. Esta es una tarea no trivial y se requiere un profundo conocimiento de la arquitectura JSF para hacerlo bien. Si necesita un control personalizado, es mejor crear un control concreto que extienda un UIComponent existente (como HtmlInputText) con un renderizador equivalente.
Si la contaminación no es un problema, existe una implementación JSF de fuente abierta en forma de Apache MyFaces.
Los detectores de acciones, como CommandButton , se invocan durante la fase Invoke Application , que es la última fase antes de la fase final de Render Response . Esto se muestra en El ciclo de vida JSF - figura 1 .
El mejor artículo que he encontrado es Jsf Component Writing , en cuanto a 2, donde leo el valor de un enlace de valor en tu componente, tienes un getter que se parece a esto
public String getBar() {
if (null != this.bar) {
return this.bar ;
}
ValueBinding _vb = getValueBinding("bar");
return (_vb != null) ? (bar) _vb.getValue(getFacesContext()) : null;
}
¿Cómo entró esto en getValueBinding? En su clase de etiqueta, método setProperties
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.");
}
}