¿Cómo funciona el atributo ‘vinculante’ en JSF? ¿Cuándo y cómo se debe usar?

Hay muchos materiales que distinguen el atributo de value y el atributo de binding en JSF.

Estoy interesado en cómo ambos enfoques difieren entre sí. Dado:

 public class User { private String name; private UICommand link; // Getters and setters omitted. } 
    

Es bastante sencillo lo que sucede cuando se especifica un atributo de value . El getter se ejecuta para devolver el valor de propiedad de name del bean User . El valor se imprime en salida HTML.

Pero no pude entender cómo funciona el binding . ¿Cómo mantiene el HTML generado un enlace con la propiedad de link del bean User ?

A continuación se muestra la parte relevante de la salida generada después del embellecimiento manual y los comentarios (tenga en cuenta que el ID j_id_jsp_1847466274_1 se generó automáticamente y que hay dos widgets de entrada ocultos). Estoy usando Sun’s JSF RI, versión 1.2.

 
Name

¿Dónde se almacena el binding aquí?

¿Como funciona?

Cuando se crea / restaura una vista JSF (archivo Facelets / JSP), se generará un árbol de componentes JSF. En ese momento, el tiempo de comstackción de la vista , todos binding atributos de binding son evaluados ( junto con id attribtues y taghandlers como JSTL ). Cuando se necesita crear el componente JSF antes de agregarlo al árbol de componentes, JSF comprobará si el atributo binding devuelve un componente preoperado (es decir, no null ) y, de ser así, lo usará. Si no se crea previamente, JSF creará automáticamente el componente “de la manera habitual” e invocará al colocador detrás del atributo de binding con la instancia del componente creado automáticamente como argumento.

En efectos, vincula una referencia de la instancia del componente en el árbol de componentes a una variable delimitada. Esta información no es de ninguna manera visible en la representación HTML generada del componente en sí. Esta información de ninguna manera es relevante para la salida HTML generada de todos modos. Cuando se envía el formulario y se restaura la vista, el árbol de componentes JSF se acaba de reconstruir desde cero y todos binding atributos de binding se volverán a evaluar como se describe en el párrafo anterior. Después de recrear el árbol de componentes, JSF restablecerá el estado de la vista JSF en el árbol de componentes.

Las instancias de componentes tienen un scope de solicitud.

Es importante saber y comprender que las instancias de componentes concretos son efectivamente de scope de solicitud. Han sido creados recientemente en cada solicitud y sus propiedades están llenas de valores del estado de vista de JSF durante la fase de restauración de la vista. Por lo tanto, si vincula el componente a una propiedad de un bean de respaldo, entonces el bean de respaldo no debería estar en un ámbito más amplio que el scope de la solicitud. Ver también JSF 2.0 especificación capítulo 3.1.5:

3.1.5 Enlaces de componentes

Los enlaces de componentes a menudo se usan junto con los JavaBeans que se instancian dinámicamente a través del recurso Managed Bean Creation (consulte la Sección 5.8.1 “VariableResolver y el VariableResolver predeterminado”). Se recomienda encarecidamente que los desarrolladores de aplicaciones coloquen beans administrados apuntados por expresiones de enlace de componentes en el ámbito de “solicitud”. Esto se debe a que colocarlo en sesión o en el scope de la aplicación requeriría seguridad de subprocesos, ya que las instancias de UIComponent dependen de la ejecución dentro de un único subproceso. También hay impactos potencialmente negativos en la administración de la memoria al colocar un enlace de componente en el ámbito de “sesión”.

De lo contrario, las instancias de componentes se comparten entre varias solicitudes, lo que posiblemente da como resultado errores de ” ID de componente duplicados ” y comportamientos “extraños” porque validadores, convertidores y oyentes declarados en la vista se vuelven a adjuntar a la instancia de componente existente de solicitud (es) anterior. Los síntomas son claros: se ejecutan varias veces, una vez más con cada solicitud dentro del mismo ámbito al que se ha vinculado el componente.

Y, bajo cargas pesadas (es decir, cuando múltiples solicitudes HTTP diferentes (hilos) acceden y manipulan la misma instancia de componente al mismo tiempo), es posible que tarde o temprano se produzca un locking de la aplicación con, por ejemplo, Stuck thread en UIComponent.popComponentFromEL o Java Threads al 100% de utilización de CPU usando richDaces UIDataAdaptorBase y su HashMap interno , o incluso alguna “extraña” IndexOutOfBoundsException o ConcurrentModificationException viene directamente del código fuente de implementación JSF mientras JSF está ocupado guardando o restaurando el estado de la vista (es decir, el seguimiento de stack indica saveState() o restreState() métodos y similares).

Usar el binding en una propiedad de frijol es una mala práctica

De todos modos, al usar el binding esta manera, vincular una instancia de componente completa a una propiedad de bean, incluso en un bean con ámbito de solicitud, es bastante raro en el caso de uso de JSF 2.xa y generalmente no es la mejor práctica. Indica un olor de diseño. Por lo general, declaras los componentes en el lado de la vista y vincula sus atributos de tiempo de ejecución como value , y quizás otros como styleClass , disabled , rendered , etc, a las propiedades de bean normales. Entonces, simplemente manipulas exactamente la propiedad de frijol que quieres en lugar de agarrar todo el componente y llamar al método setter asociado con el atributo.

En los casos en que un componente necesita ser “construido dinámicamente” en base a un modelo estático, es mejor usar ver las tags de tiempo de comstackción como JSTL , si es necesario en un archivo de etiqueta , en lugar de createComponent() , new SomeComponent() , getChildren().add() y qué no. Consulte también Cómo refactorizar el fragmento de JSP antiguo a un equivalente de JSF.

O bien, si un componente necesita ser “renderizado dinámicamente” en base a un modelo dynamic, entonces simplemente use un componente iterador ( , , etc.). Vea también Cómo agregar dinámicamente componentes JSF .

Los componentes compuestos es una historia completamente diferente. Es completamente legítimo vincular componentes dentro de una con el componente de respaldo (es decir, el componente identificado por . Ver también ao dividir java.util.Date sobre dos h: campos inputText que representan hora y minuto con f: convertDateTime y ¿Cómo implementar una lista dinámica con un componente compuesto JSF 2.0?

Solo use el binding en el scope local

Sin embargo, a veces le gustaría saber sobre el estado de un componente diferente desde dentro de un componente en particular, más a menudo en casos de uso relacionados con la validación dependiente de la acción / valor. Para eso, el atributo de binding se puede usar, pero no en combinación con una propiedad de bean. Puede especificar una en el nombre de variable único del ámbito local de EL en el atributo de binding como por ejemplo binding="#{foo}" y el componente se encuentra durante la respuesta de representación en otra parte de la misma vista directamente como referencia UIComponent disponible por #{foo} . Aquí hay varias preguntas relacionadas donde tal solución se ha usado en la respuesta:

  • Valide la entrada según sea necesario solo si se presiona cierto botón de comando
  • ¿Cómo renderizar un componente solo si no se procesa otro componente?
  • JSF 2 dataTable fila índice sin dataModel
  • Primefaces dependientes selectOneMenu y required = “true”
  • Valide un grupo de campos según sea necesario cuando al menos uno de ellos esté lleno
  • ¿Cómo cambiar la clase css para el campo de entrada y la etiqueta cuando falla la validación?
  • Obtener un componente definido por JSF con Javascript
  • Use una expresión EL para pasar una ID de componente a un componente compuesto en JSF

    (y eso es solo del último mes …)

Ver también:

  • Cómo usar el enlace de componentes en JSF ¿verdad? (componente de ámbito de solicitud en bean con ámbito de sesión)
  • Ámbito de la vista: java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
  • El atributo de vinculación hace que se encuentre una ID de componente duplicada en la vista

cada componente JSF se renderiza en HTML y tiene control completo sobre qué HTML produce. Hay muchos trucos que puede utilizar JSF, y exactamente cuál de esos trucos se utilizará depende de la implementación de JSF que esté utilizando.

  • Asegúrese de que cada entrada tenga un nombre totalmente único, de modo que cuando el formulario se envíe de vuelta al árbol de componentes que lo generó, sea fácil decir dónde cada componente puede leer su forma de valor.
  • El componente JSF puede generar javascript que se envía de vuelta al seridor, el javascript generado sabe a dónde está ligado cada componente, porque fue generado por el componente.
  • Para cosas como hlink, puede incluir información vinculante en la url como parámetros de consulta o como parte de la url misma o como parámetros matrx. por ejemplo.

    http:..../somelink?componentId=123 permitiría que jsf busque en el árbol de componentes para ver que se hizo clic en el enlace 123. o podría e htp:..../jsf;LinkId=123

La forma más sencilla de responder a esta pregunta es crear una página JSF con solo un enlace, luego examinar la salida html que produce. De esta forma sabrá exactamente cómo sucede esto usando la versión de JSF que está usando.

    Intereting Posts