【发布时间】:2015-07-24 06:11:27
【问题描述】:
也许这是一个愚蠢的问题,但在 Primefaces 的 <p:dialog> 中有一个名为 appendTo 的属性,在手册中描述为:
将对话框附加到给定搜索定义的元素 表达。
我不知道它有什么用?
【问题讨论】:
标签: jsf-2 primefaces
也许这是一个愚蠢的问题,但在 Primefaces 的 <p:dialog> 中有一个名为 appendTo 的属性,在手册中描述为:
将对话框附加到给定搜索定义的元素 表达。
我不知道它有什么用?
【问题讨论】:
标签: jsf-2 primefaces
来自PrimeFaces User Guide(目前第185页):
不要将对话框放置在表格中,容器喜欢具有相对定位或不可见的 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)【讨论】:
<p:dialog> 放在其他地方,但如果它位于其他组件中,我应该使用appendTo 以避免出现问题?如果我将它放在单独的表单中(当然不是嵌套的)并且它是<h:body> 的下一个孩子,我真的不需要它。我对吗?谢谢。
This is not a limitation but a result of DOM model. - 有趣的是他们的措辞。这是 PF 的一个限制——技术上没有什么可以阻止他们在绝对定位的容器(如布局单元)内正确定位对话框。他们只是没有那样实施。当然,对话框可能会被overflow: hidden 等容器的边界截断,但这是另一回事。
PrimeFaces 文档在这一点上有点稀疏。 appendToBody / appendTo(5.0 之前)解决(或试图解决)PrimeFaces 组件未获得正确 z-Index 的问题,这意味着它不会以应有的方式出现在其他元素之前或之后。但是,此功能存在问题,因为它可能会导致其他问题,例如p:commandbutton action doesn't work inside p:dialog
tl;博士:
不要使用appendTo / appendToBody。相反,对话框(连同 ConfirmDialog 和 OverlayPanel)应始终位于组件层次结构的根部,作为<h:body> 的直接后代。这将使它们可靠地工作。在这种情况下使用appendTo / appendToBody 是不必要的。
实现此目的的一个好方法是为这些组件创建一个(或多个)单独的 XHTML 文件(“dialogs.xhtml”),然后将其包含在您的主 XHTML 文件或模板中(例如使用 <ui:include>) .如果您希望对话框保留在使用它们的 XHTML 文件中,另一种解决方案是结合使用 <ui:define> 和 <ui:insert>。
继续阅读以了解详细信息:-)
一些 PrimeFaces 组件(例如对话框)应该显示在其他元素之上。
例如:
如果您使用<p:dialog ...modal="true">,并使对话框可见,您会在前景中看到一个对话框,出现在页面其余部分的上方,页面的其余部分被透明层覆盖。
例如,您可以在 PF Showcase for dialogs(按钮“模态”)中看到这一点。
在幕后,即在页面的 DOM 中,发生了两件事:
<body> 的末尾创建一个新的<div>(“模态覆盖”)。这个 div 获取 CSS 样式:z-index: 1000; position: absolute; opacity: .30;。这使其透明并覆盖整个页面,以获得“模态”效果。z-index: 1001; position:fixed;。请注意,z-index 比模态叠加层大一,因此对话框出现在叠加层上方。但是,这并不总是有效。原因是 CSS 的一个方面称为stacking context。细节有点复杂,但基本上它表示页面元素的 z-index 仅与同一父元素内的其他元素进行比较。特别是,一个元素可能出现在另一个元素的后面,即使它具有更高的 z-index,如果具有高 z-index 的元素包含在具有较低 z-index 的元素中。 p>
简短(安全)的版本是:为了确保 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 的 @ 987654324@函数)。这样组件就在 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) 中再次出现。这表明这种“在 JSF 背后”进行的 DOM 操作相当冒险,应该避免 - 因此我建议不要使用 appendTo / appendToBody。
【讨论】:
</body> 之前创建一个<ui:insert name="dialog"/>,并使用一个<ui:define name="dialog>… </ui:define>,在其中定义该页面的对话框。这样你就可以与页面保持对话