Naming Container en JSF2 / PrimeFaces

¿Cuáles son los posibles contenedores de nombres en PrimeFaces? ¿Por qué es necesario agregar naming container id para la llamada de actualización Ajax cuando queremos actualizar algún control de UI en el formulario usando update=":mainForm:MainAccordian:userNameTextbox" ?

Después de haber analizado IntelliJ todos mis javax.faces.component.NamingContainer para las implementaciones de javax.faces.component.NamingContainer aquí está lo que encontré:

De PrimeFaces 5.3

  • AccordionPanel
  • Carrusel
  • Columnas
  • Cuadrícula de datos
  • Lista de datos
  • DataScroller
  • Tabla de datos
  • Página
  • anillo
  • SubTable
  • Subvista
  • TabView
  • TreeTable
  • UIData
  • UITabPanel

De MyFaces 2.1

  • HtmlDataTable
  • HtmlForm
  • UITree
  • UIForm

¿Cuál es el posible contenedor de nombres en Prime faces?

En JSF, los contenedores de nombres derivan de UINamingContainer .

¿Por qué es necesario adjuntar la identificación del contenedor de nombres para la llamada de actualización de Ajax cuando queremos actualizar algún control de UI en el formulario usando update = “: mainForm: MainAccordian: userNameTextbox”

Digamos, y agregas otro a tu página, obtendrás un error que dice que tienes una identificación duplicada . Puede buscarlo aquí en JavaDoc para UIComponent.setId (String) :

Establezca el identificador de componente de este UIComponent (si hay alguno). Los identificadores de los componentes deben obedecer las siguientes restricciones de syntax: No debe ser una cadena de longitud cero. El primer carácter debe ser una letra o un guión bajo (‘ ‘). Los caracteres subsiguientes deben ser una letra, un dígito, un guión bajo (‘ ‘) o un guión (‘-‘).

.. además, importante para ti:

El identificador especificado debe ser único entre todos los componentes (incluidas las facetas) que son descendientes del antecesor UIComponent más cercano que es un NamingContainer , o dentro del scope de todo el árbol de componentes si no existe un ancestro que sea un NamingContainer.

Significa que no puede tener dos componentes con el mismo ID bajo el mismo NamingContainer (si no tiene NamingContainer, el árbol completo se cuenta como NamingContainer). Por lo tanto, necesita agregar un NamingContainer, como a

Tomemos el siguiente ejemplo:

        

.. y quieres hacer una actualización de userNameTextbox . ¿A qué userNameTextbox te refieres porque hay 3?

¿El primero? Luego actualiza userNameTextbox

¿El segundo? A continuación, actualice container1: userNameTextbox

¿El tercero? A continuación, actualice container2: userNameTextbox

Nombrar contenedores en Prime Faces

Como podemos ver en JSF Reference

NamingContainer es una interfaz que debe implementar cualquier UIComponent que quiera ser un contenedor de nombres. Los nombres de los contenedores afectan el comportamiento de los métodos UIComponent.findComponent (java.lang.String) y UIComponent.getClientId ();

Entonces, para encontrar contenedores de nombres en PF, debe verificar la jerarquía de la interfaz de NamingContainer. En Eclipse puede hacer esto, por ejemplo, mediante el atajo Ctrl + T en NamingContainer.

En PF 5.3 hay, por ejemplo: AccordionPanel, Carrusel, Columns, DataGrid, DataList, DataScroller, DataTable, Ring, SubTable, TabView, Tree, TreeTable.

Nombrar la influencia del contenedor en la identificación del componente

  1. Comportamiento por defecto

Naming Container proporciona un ámbito de denominación para sus componentes secundarios. Por lo tanto, siempre agrega el prefijo a la identificación de sus hijos. Así que el componente id of child es: parent_component_id".concat(":").concat("component_id") . Hay un pro tip que he leído en JavaServer Faces 2.0, The Complete Reference que incluso si no agrega NamingContainer a su la página siempre es automáticamente añadida por JSF 🙂 También existe un algoritmo especial para esta creación (Capítulo 11: Creación de un componente personalizado de interfaz de usuario -> Cuadro denominado “Reglas para crear el componente de nivel superior para un componente compuesto”). Por supuesto, cuando no establece ID, se generará automáticamente (por ejemplo, j_idt234). Por lo tanto, el ID de componente completo puede tener este aspecto: “j_idt123: j_idt234: j_idt345”.

  1. Cambiar el separador de nombre del componente (desde JSF 2.x)

Hay una manera de anular el separador de nombre de componente predeterminado (“:”). Puede definirlo en web.xml como context-param con el nombre javax.faces.SEPARATOR_CHAR. Por ejemplo:

  javax.faces.SEPARATOR_CHAR -  
  1. Atributo UIForm “prependId”

Para evitar agregar el scope al componente secundario, hay un atributo (solo en el componente UIForm). Pero esta no es una solución recomendada. Eche un vistazo, por ejemplo, a uiform-with-prependid-false-breaks-fajax-render

Uso de identificación de componentes (por ejemplo, en “actualización”, “proceso”)

  1. Identificación completa

Puede usar la identificación completa: “componentParent: component”. Esto no es recomendable (el código será frágil; cualquier cambio de id. Hará que sea necesario cambiar los ID en muchos lugares).

  1. Id. Relativos en el mismo nivel de nomenclatura del contenedor

Dentro de un contenedor de nombres, puede usar el ID de componente simple.

  1. PrimeFaces Search Expression Framework

Si no conoce esta función, eche un vistazo a la documentación de PrimeFaces. Prime Faces proporciona el Marco de Expresión de Búsqueda con un par de mecanismos muy útiles.

Puede buscar por palabras clave.

Las palabras clave son la forma más fácil de referenciar los componentes, se resuelven en los identificadores, de modo que si cambia un identificador, la referencia no necesita cambiar. Core JSF proporciona un par de palabras clave y PrimeFaces proporciona más junto con el soporte de expresiones compuestas.

Ejemplos: @ this (componente actual), @form (forma ancestral más cercana), @namingcontainer (contenedor de nombres ancestro más cercano), @parent, @widgetVar (nombre). También puede mezclar esas palabras clave en rutas bastante complejas (Expresiones compuestas), por ejemplo: @form: @parent, @this: @parent: @parent

La segunda posibilidad que PF le ofrece son los selectores PrimeFaces (PFS).

PFS integra la API jQuery Selector con el modelo de referencia de componentes JSF, de modo que la referencia se puede hacer usando la API jQuery Selector en lugar del modelo JSF basado en la identificación del núcleo.

Entonces puedes por ejemplo:

  • actualizar todos los elementos del formulario por update="@(form)"
  • actualizar todas las tablas de datos por update="@(.ui-datatable)"
  • actualizar todos los componentes que tienen styleClass llamado myStyle por update="@(.myStyle)"

Una herramienta bastante poderosa.