Pregunta La propiedad 'appendTo' del diálogo de Primefaces, ¿para qué sirve?


Tal vez es una pregunta tonta, pero en Primefaces <p:dialog> hay propiedad que llamó appendTo que se describe en el manual como:

Añade el diálogo al elemento definido por la búsqueda dada   expresión.

No me puedo dar cuenta de lo que es útil?


16
2018-05-13 05:48


origen


Respuestas:


Desde el Guía del usuario de PrimeFaces (actualmente p.185):

No coloque el cuadro de diálogo dentro de las tablas, los contenedores le gustan los divs con posicionamiento relativo o no visible   desbordamiento definido, en casos como esta funcionalidad podría estar roto. Esto no es una limitación   pero un resultado del modelo DOM. Por ejemplo, el diálogo dentro de una unidad de diseño, tabview, acordeón son una   par de ejemplos. Lo mismo se aplica a confirmDialog también.

Puedes superar esto usando appendTo="@(body)" y tu dialog se adjuntará como un niño de la <body> nodo.

Uno de los principales dialog la opción es modal y podrías terminar rápidamente con tu diálogo detrás de la superposición si no estás usando appendTo Como se muestra abajo:

enter image description here

Ver también http://forum.primefaces.org/viewtopic.php?f=3&t=16504


Notas:


23
2018-05-13 08:40



Los documentos de PrimeFaces son un poco escasos en este punto. appendToBody / appendTo (anterior a 5.0) resuelve (o intenta resolver) un problema donde un componente PrimeFaces no obtiene el índice z correcto, lo que significa que no aparece antes o detrás de otros elementos de la manera que debería. Sin embargo, esta característica es problemática porque puede causar otros problemas como p: la acción del botón de comando no funciona dentro de p: diálogo

tl; dr:

No utilice appendTo / appendToBody. En cambio, los cuadros de diálogo (junto con ConfirmDialog y OverlayPanel) siempre deben estar en la raíz de la jerarquía del componente, como un descendiente directo de <h:body>. Esto hará que funcionen de manera confiable. En ese caso usando appendTo / appendToBody es innecesario

Una buena forma de lograr esto es tener uno (o varios) archivos XHTML separados para estos componentes ("dialogs.xhtml"), que luego se incluirán en su archivo o plantilla XHTML principal (por ejemplo, usando <ui:include>) Otra solución es usar un <ui:define> en combinación con un <ui:insert> si desea que los cuadros de diálogo permanezcan en el archivo XHTML donde se usan.

Sigue leyendo para más detalles :-)


El problema

Algunos componentes de PrimeFaces (como los cuadros de diálogo) se deben mostrar encima de otros elementos.

Por ejemplo:

Si utiliza <p:dialog ...modal="true">y para hacer que el diálogo sea visible, se obtiene un diálogo en primer plano, que aparece sobre el resto de la página, con el resto de la página cubierto por una capa transparente. Puedes ver esto, por ejemplo, en PF Showcase para diálogos (botón "Modal").

Detrás de escena, es decir, en el DOM de la página, suceden dos cosas:

  • un nuevo <div>(la "superposición modal") se crea al final de la <body>. Este div obtiene los estilos CSS: z-index: 1000; position: absolute; opacity: .30;. Esto lo hace transparente y cubre toda la página, para obtener el efecto "modal".
  • el div (existente, pero invisible) del diálogo en sí se hace visible, y obtiene el estilo z-index: 1001; position:fixed;. Tenga en cuenta que el índice z es uno más grande que la superposición modal, por lo que el cuadro de diálogo aparece encima de la superposición.

sin embargo, Esto no siempre funciona. La razón de esto es un aspecto de CSS llamado contexto de apilamiento. Los detalles son un poco complejos, pero básicamente dice que el índice Z de un elemento de página solo se compara con otros elementos dentro del mismo elemento principal. En particular, un elemento puede aparecer detrás de otro elemento a pesar de que tiene un índice z más alto, si el elemento con el alto índice z está contenido en un elemento con un índice Z más bajo.

La versión corta (segura) es: Para estar seguro de que el índice Z funciona como se espera, todos los elementos involucrados deberían ser hermanos en el DOM.

Ahora, en esta situación particular, la superposición modal debe estar justo en la parte superior de la jerarquía DOM (es decir, dentro <body>), de lo contrario no puede aparecer de manera confiable sobre el resto de la página. Sin embargo, el div del diálogo mismo está en algún lugar más profundo en el DOM (correspondiente a la posición del <p:dialog> etiqueta en la fuente XHTML). Ahora tenemos un problema

En la práctica, esto significa que la superposición puede aparecer encima del diálogo, oscureciéndolo y bloqueándolo. De forma similar, si el diálogo no es modal, puede aparecer detrás de otros elementos en la página.

Lo insidioso de este problema es que depende de la estructura del resto de la página (específicamente, si el resto de la página usa CSS que crea un nuevo contexto de apilamiento). Asi que <p:dialog> puede parecer que funciona inicialmente, y de repente muestra incorrectamente después de un cambio en otro lugar.

Cómo ayuda 'appendTo'

Como se explicó anteriormente, el problema ocurre porque el HTML procesado para el componente PrimeFaces está en algún lugar en el fondo del DOM, mientras que debería ser un hijo directo de <body> para que el índice Z funcione correctamente

Cuando appendToBody / appendTo se utiliza, PrimeFaces incluirá Javascript en la página representada que simplemente mueve el nodo DOM del componente PrimeFaces hasta el final de <body> (usando JQuery's appendTo función). De esta forma, el componente está en el lugar correcto en el DOM, y el índice z funciona.

El problema con el uso de 'appendTo'

Mientras que la reorganización de DOM realizada por appendTo resuelve el problema con CSS y z-index, introduce otro problema (potencial):

El DOM del lado del cliente ya no se corresponde con el estado de la página del lado del servidor mantenido por JSF (llamado ver)

Ahora, una de las características centrales de JSF es que espera que la estructura HTML / DOM del lado del cliente se corresponda con la vista del lado del servidor; después de todo, JSF construyó el HTML a partir de esa vista. Si se infringe esa regla (generalmente manipulando el lado del cliente DOM), se obtienen todo tipo de problemas extraños, como que JSF ignora los campos de formulario o los valores de un envío, o sobrescribe parte de sus modificaciones en las actualizaciones de AJAX.

En este caso, los problemas causados ​​por mover el nodo DOM del componente PrimeFaces incluyen:

  • Si el componente PrimeFaces es parte de un <h:form>, no funcionará correctamente (porque no estará dentro del <form> etiqueta del lado del cliente debido a la mudanza).
    En realidad, esto se menciona en los documentos de PrimeFaces, junto con la solución alternativa: en lugar de poner el componente en un formulario, ponga un formulario dentro el componente - entonces la forma se moverá con el componente.
  • Si el área donde JSF originalmente prestó el componente PrimeFaces se actualiza utilizando la función AJAX de JSF, JSF eliminará el área para actualizar desde el DOM, luego volverá a representar el componente, ya que no sabe si se movió a otro lugar.
    En las versiones anteriores de PrimeFaces, esto causaba que el componente apareciera dos veces en el DOM (con el mismo id), lo que causó problemas con los envíos posteriores. Esto fue corregido para PrimeFaces 4.0 ( Problema 5636: Dialog appendToBody & dynamic no elimina el antiguo elemento dom ), pero volvió a ocurrir en 5.0 (problema # 367)

Esto muestra que este tipo de manipulación de DOM "detrás de la espalda de JSF" es bastante arriesgado y debe evitarse, así que mi consejo es no utilizar appendTo / appendToBody.


15
2017-11-20 11:24