也许这是一个愚蠢的问题,但是在Primefaces的<p:dialog>
那个名为appendTo
的财产中,在手册中描述为:
将对话框追加到给定搜索定义的元素 表达
我无法意识到它有用吗?
答案 0 :(得分:27)
来自PrimeFaces User Guide(目前第185页):
不要在对象内放置对话框,容器喜欢具有相对定位的div或具有不可见的div 溢出已定义,在这些功能可能被破坏的情况下。这不是限制 但是DOM模型的结果。例如布局单元内的对话框,tabview,手风琴是一个 几个例子。同样适用于confirmDialog。
您可以使用appendTo="@(body)"
来解决此问题,并且您的dialog
将作为<body>
节点的子级附加。
其中一个主要的dialog
选项是modal
,如果你没有使用appendTo
,你很快就可以在叠加层后面找到对话框,如下所示:
另见http://forum.primefaces.org/viewtopic.php?f=3&t=16504
备注:强>
appendToBody="true"
。这已经改为5.0。dialog
包含某些按钮,请不要忘记<h:form>
围绕它们(参见Proper Construct for Primefaces Dialog)答案 1 :(得分:20)
PrimeFaces文档在这一点上有点稀疏。 appendToBody
/ appendTo
(5.0之前)解决(或尝试解决)PrimeFaces组件未获得正确z-Index的问题,这意味着它不会出现在其他元素之前或之后应该。但是,此功能存在问题,因为它可能会导致其他问题,例如p:commandbutton action doesn't work inside p:dialog
<强> TL; DR:强>
请勿使用appendTo
/ appendToBody
。相反,Dialogs(以及ConfirmDialog和OverlayPanel)应始终位于组件层次结构的根,作为<h:body>
的直接后代。这将使它们可靠地工作。在这种情况下,使用appendTo
/ appendToBody
是不必要的。
实现这一目标的一个好方法是为这些组件(&#34; dialogs.xhtml&#34;)提供一个(或多个)单独的XHTML文件,然后将其包含在主XHTML文件或模板中(例如使用<ui:include>
)。另一种解决方案是,如果您希望对话框保留在使用它们的XHTML文件中,请将<ui:define>
与<ui:insert>
结合使用。
继续阅读详情: - )
某些PrimeFaces组件(如对话框)应显示在其他元素之上。
例如:
如果使用<p:dialog ...modal="true">
,并使对话框可见,则会在前景中显示一个对话框,显示在页面的其余部分上方,页面的其余部分由透明层覆盖。
您可以在PF Showcase for dialogs(按钮&#34;模态&#34;)中看到这一点。
在幕后,即在页面的DOM中,会发生两件事:
<div>
的末尾创建了一个新的<body>
(&#34;模态叠加&#34;)。这个div获得了CSS样式:z-index: 1000; position: absolute; opacity: .30;
。这使得它透明并覆盖整个页面,以获得&#34;模态&#34;效果。z-index: 1001; position:fixed;
。请注意,z-index比模式叠加大1,因此对话框显示在叠加层上方。然而,这并不总是有效。其原因是CSS的一个方面,称为stacking context。细节有点复杂,但基本上它表示页面元素的z-index仅与同一父元素内的其他元素进行比较。特别是,元素可能出现在另一个元素后面,即使它具有更高的z-index,如果具有高z-index的元素包含在具有更低z-index 的元素中。
短(安全)版本是:为了确保z-index按预期工作,所有相关元素应该是DOM中的兄弟。
现在,在这种特殊情况下,模态覆盖必须位于DOM层次结构的顶部(即<body>
内),否则它无法可靠地出现在页面的其余部分之上。但是,对话框本身的div位于DOM的更深处(对应于源XHTML中<p:dialog>
标记的位置)。 现在我们遇到了问题。
实际上,这意味着叠加层可能出现在对话框上方,从而遮挡并阻挡它。同样,如果对话框不是模态的,它可能会出现在页面中的其他元素后面。
这个问题的阴险之处在于它取决于页面其余部分的结构(具体来说,页面的其余部分是否使用CSS来创建新的堆叠上下文)。因此,<p:dialog>
最初可能会起作用,然后在其他地方发生更改后突然显示错误。
如上所述,出现问题是因为为PrimeFaces组件呈现的HTML位于DOM的深处,而它需要是<body>
的直接子项才能使z-index正常工作。
当使用appendToBody
/ appendTo
时,PrimeFaces将在呈现的页面中包含Javascript,只需将PrimeFaces组件的DOM节点移动到<body>
的末尾(使用JQuery&#39; s appendTo函数)。这样,组件就位于DOM中的正确位置,并且z-index可以正常工作。
虽然appendTo
执行的DOM重组解决了CSS和z-index的问题,但它引入了另一个(潜在的)问题:
客户端DOM不再对应于JSF维护的服务器端页面状态(称为视图)。
现在,JSF的一个核心功能是它希望客户端HTML / DOM结构与服务器端视图相对应 - 毕竟,JSF从该视图构造了HTML。如果违反了该规则(通常通过操纵DOM客户端),则会遇到各种奇怪的问题,例如JSF忽略提交中的表单字段或值,或者覆盖AJAX更新中的部分修改。
在这种情况下,移动PrimeFaces组件的DOM节点引起的问题包括:
<h:form>
的一部分,它将无法正常工作(因为移动时它不会位于<form>
标签客户端内。)id
),这导致后来提交的问题。这已针对PrimeFaces 4.0(Issue 5636: Dialog appendToBody & dynamic doesn't remove the old dom element)修复,但在5.0(issue #367)中重新出现。这表明这种DOM操纵&#34;背后的JSF&#34;风险很大,应该避免 - 因此我建议不要使用appendTo
/ appendToBody
。