La propriété 'appendTo' de dialogue de Primefaces, à quoi sert-elle?
peut-être que c'est une question stupide, mais dans Primefaces est <p:dialog>
il y a des biens qui appelle appendTo
qui est décrit dans le manuel d'utilisation:
ajoute la boîte de dialogue à l'élément défini par la recherche donnée expression.
Je ne peux pas réaliser à quoi ça sert?
2 réponses
PrimeFaces Guide De L'Utilisateur(actuellement p. 185):
ne pas placer de dialogue à l'intérieur des tables, les conteneurs aiment les divs avec positionnement relatif ou avec non visible débordement défini, dans les cas comme ces fonctionnalités peuvent être brisées. Ce n'est pas une limitation mais un résultat du modèle DOM. Par exemple, le dialogue à l'intérieur d'une unité de mise en page, tabview, accordéon sont un quelques exemples. Même s'applique à confirmDialog.
Vous pouvez surmontez cela en utilisant appendTo="@(body)"
et dialog
sera attaché comme un enfant du <body>
nœud.
l'Un des principaux dialog
option modal
et vous pourrait rapidement se retrouver avec votre boîte de dialogue derrière la superposition si vous n'êtes pas à l'aide de appendTo
comme indiqué ci-dessous:
Voir aussi http://forum.primefaces.org/viewtopic.php?f=3&t=16504
Notes:
- avant PrimeFaces 5.0, l'attribut à définir était
appendToBody="true"
. Ceci a été modifié pour 5.0. - Si votre
dialog
contient quelques boutons n'oubliez pas de les entourer par<h:form>
(voir construction correcte de la boîte de dialogue Primefaces)
Le PrimeFaces docs sont un peu clairsemée sur ce point. appendToBody
/appendTo
(avant 5.0) résout (ou tente de résoudre) un problème où un composant PrimeFaces n'obtient pas le bon Index z, ce qui signifie qu'il n'apparaît pas avant ou derrière d'autres éléments comme il devrait. Cependant, cette fonctionnalité est problématique car elle peut causer d'autres problèmes comme p:commandbutton action ne fonctionne pas à l'intérieur de p:boîte de dialogue
tl; dr:
ne pas utiliser utilisez appendTo
/appendToBody
. Au lieu de cela, les dialogues (avec ConfirmDialog et OverlayPanel) devraient toujours être à la racine de la hiérarchie des composants, en tant que descendant direct de <h:body>
. Cela permettra de les faire fonctionner de manière fiable. Dans ce cas, à l'aide de appendTo
/appendToBody
n'est pas nécessaire.
une bonne façon d'y parvenir est d'avoir un (ou plusieurs) fichier XHTML séparé pour ces composants ("dialogues.xhtml"), qui est alors inclus dans votre fichier ou modèle XHTML principal (par exemple en utilisant <ui:include>
). Une autre solution est d'utiliser un <ui:define>
en combinaison avec un <ui:insert>
si vous voulez que les dialogues restent dans le fichier XHTML où ils sont utilisés.
Lisez la suite pour les détails :-)
Le problème
certaines composantes de PrimeFaces (comme les dialogues) doivent être affichées au-dessus d'autres éléments.
Par exemple:
Si vous utilisez <p:dialog ...modal="true">
, et rendre la boîte de dialogue visible, vous obtenez une boîte de dialogue au premier plan, apparaissant au-dessus du reste de la page, avec le reste de la page couverts par une couche transparente.
Vous pouvez le voir par exemple dans le PF Vitrine pour les boîtes de dialogue (bouton "Modal").
en coulisses, c'est à dire dans le DOM, il se passe deux choses:
- un nouveau
<div>
(la "superposition modale") est créée à la fin de l'<body>
. Cette div obtient les styles CSS:z-index: 1000; position: absolute; opacity: .30;
. Cela le rend transparent et couvrant toute la page ,pour obtenir le " modal" effet. - le div (existant, mais invisible) du dialogue lui-même est rendu visible, et obtient le style
z-index: 1001; position:fixed;
. Note l'index z est plus grand que le recouvrement modal, donc la boîte de dialogue apparaît au-dessus du recouvrement.
Toutefois, cela ne fonctionne pas toujours. La raison en est un aspect de CSS appelé empilement contexte. Les détails sont un peu complexes, mais fondamentalement il dit que le z-index d'un élément de page est seulement comparé à d'autres éléments à l'intérieur du même élément parent. En particulier, un élément peut apparaître derrière un autre élément même s'il a un indice z plus élevé, si l'élément à indice z élevé est contenu dans un élément à indice z inférieur.
court (safe) version: Pour être certains que les z-index fonctionne comme prévu, tous les éléments concernés devraient être des frères et sœurs dans le DOM.
Maintenant, dans cette situation particulière, la superposition modale doit être en haut de la hiérarchie DOM (c'est-à-dire à l'intérieur de <body>
), sinon il ne peut pas apparaître de façon fiable au-dessus du reste de la page. Cependant, le div du dialogue lui-même est quelque part plus profond dans le DOM (correspondant à la position du <p:dialog>
dans la balise source XHTML). Maintenant, nous avons un problème.
en pratique, cela signifie que la superposition peut apparaître au-dessus de la boîte de dialogue, ce qui l'obscurcit et la bloque. De même, si le dialogue n'est pas modale, il peut apparaître derrière d'autres éléments dans la page.
la chose insidieuse à propos de ce problème est qu'il dépend de la structure du reste de la page (plus précisément, si le reste de la page utilise CSS qui crée un nouveau contexte de cumul). Donc <p:dialog>
peut sembler fonctionner initialement, puis apparaît soudainement incorrectement après un changement ailleurs.
Comment "appendTo' aide
comme expliqué ci-dessus, le problème se produit parce que le HTML rendu pour le composant PrimeFaces est quelque part au fond du DOM, alors qu'il aurait besoin d'être un enfant direct de <body>
pour que le z-index fonctionne correctement.
Quand appendToBody
/appendTo
est utilisé, PrimeFaces va inclure du Javascript dans le rendu de la page qui tout simplement déplace le noeud DOM du composant PrimeFaces à la fin de <body>
(en utilisant JQuery appendTo fonction). De cette façon, le composant est au bon endroit dans le DOM, et z-index fonctionne.
Le problème avec l'aide de 'appendTo'
alors que la réorganisation de DOM effectuée par appendTo
résout le problème avec CSS et Z-index, il introduit un autre problème (potentiel):
le DOM côté client ne correspond plus à l'état de page Côté Serveur maintenu par JSF (appelé view).
maintenant, L'une des principales caractéristiques de JSF est qu'elle s'attend à ce que la structure HTML/DOM côté client corresponde à la vue côté serveur - après tout, JSF a construit le HTML à partir de ce point de vue. Si cette règle est violée (habituellement en manipulant le côté client DOM), vous obtenez toutes sortes de problèmes bizarres, tels que l'ignorance par JSF des champs de formulaires ou des valeurs dans un submit, ou l'écrasement d'une partie de vos modifications sur les mises à jour AJAX.
dans ce cas, les problèmes causés par le déplacement du noeud DOM du composant PrimeFaces incluent:
- si le composant PrimeFaces fait partie d'un
<h:form>
, il ne fonctionnera pas correctement (parce qu'il ne sera pas à l'intérieur de l'<form>
balise côté client en raison du déplacement).
Ceci est en fait mentionné dans les docs PrimeFaces, avec la solution de contournement: au lieu de mettre le composant dans une forme, mettez une forme à l'intérieur le composant-alors le formulaire se déplacera avec le composant. - si la zone où JSF a initialement rendu le composant PrimeFaces est mise à jour en utilisant la fonctionnalité AJAX de JSF, JSF supprimera la zone à mettre à jour du DOM, alors rendre le composant de nouveau, comme il ne sait pas qu'il a été déplacé ailleurs.
Dans les anciennes versions de PrimeFaces, cela a fait apparaître le composant dans le DOM deux fois (avec le mêmeid
), ce qui a causé des problèmes avec les soumissions ultérieures. Ceci a été corrigé pour PrimeFaces 4.0 (Problème 5636: Dialogue appendToBody & dynamique n'est pas supprimer l'ancien élément du dom), mais réapparaît dans 5.0 (question n ° 367).
cela montre que ce TYPE DE DOM la manipulation "derrière le dos de JSF" est assez risquée et devrait être évitée - d'où mon conseil de ne pas utiliser appendTo
/appendToBody
.