PrimeFaces 标记在 Liferay 7.0 中导航后仍然存在
PrimeFaces markup remains after navigation in Liferay 7.0
我注意到,当我通过 GET 从包含某些 PrimeFaces 组件的页面导航时,这些组件的标记将出现在下一页的左上角。
此问题发生在以下组件(可能还有其他组件)中:
p:tooltip
p:columnToggler
p:notifiactionBar
p:selectOneMenu
p:autoComplete
p:confirmDialog
p:dialog
p:draggable
p:menuButton
p:selectCheckboxMenu
p:selectOneMenu
p:splitButton
有什么方法可以阻止此标记在导航后出现?
更新:此问题已被确认为 Liferay Faces 项目中的错误,并已作为 Bridge Ext 5.0.3 的一部分得到修复:FACES-3328.
说明
这个问题是由于 PrimeFaces(最初是为 webapps 设计的)和 Liferay 7.0/SennaJS/Portlets 之间的不兼容造成的。 PrimeFaces 假定它在 webapp 环境中使用,在该环境中它可以控制页面上的所有标记,因此许多使用 JavaScript 帮助呈现的组件将其标记附加到 <body>
标记。
这是 PrimeFaces 正在做的超级简化版本:
<body>
<script>
var dynDiv = document.createElement("div");
var text = document
.createTextNode("I was created dynamically via JavaScript!");
dynDiv.appendChild(text);
document.body.appendChild(dynDiv);
</script>
</body>
但是,在 portlet 环境中,portlet 只能控制 <body>
标记内的 <div>
portlet 标记。但是由于 PrimeFaces 假定一个 webapp 环境,它仍然将标记附加到 <body>
:
<body>
<div id="myPrimeFacesPortlet">
<script>
var dynDiv = document.createElement("div");
var text = document
.createTextNode("I was created dynamically via JavaScript!");
dynDiv.appendChild(text);
document.body.appendChild(dynDiv);
</script>
</div>
</body>
在 Liferay 7.0 之前,这不是问题,因为每次导航都会导致整个页面加载,并且 PrimeFaces JavaScript 创建的所有动态元素都会被破坏。现在使用 Liferay 7.0 the Single Page Application engine of SennaJS is used to make sure that only necessary parts of the page are loaded and rendered on navigation。现在,当您通过 SennaJS 离开 PrimeFaces portlet 时,所有 PrimeFaces CSS 将与 portlet <div>
一起被删除。动态元素未被删除,PrimeFaces CSS 已卸载,因此无法再隐藏它们。
解决方案
这个问题有几种可能的解决方案(我已经按照从好到坏的顺序排列):
如果组件具有 appendTo
属性,请确保将标记附加到 portlet 标记内的元素:appendTo="@this"
、appendTo="@id(#{portletNamespace})"
(对于最外层<div>
的 portlet)或 appendTo="@form"
也应该工作(尽管 appendTo="@root"
似乎不工作)(参见 the PF User Guide (p. 558) for more details on the "Search Expression Framework")。
永久隐藏 CSS 的动态元素。为确保 CSS 不会在 SennaJS 导航中被删除,请设置 data-senna-track="permanent"
:
<h:head>
<!--You'll need to look at the CSS for each element (not just tooltip)
to figure out what CSS classes should be hidden. -->
<style id="hidePrimeFacesLeftoverMarkupWorkaroundCSS"
data-senna-track="permanent">
.ui-tooltip {
display: none;
}
</style>
</h:head>
更多信息:
我注意到,当我通过 GET 从包含某些 PrimeFaces 组件的页面导航时,这些组件的标记将出现在下一页的左上角。
此问题发生在以下组件(可能还有其他组件)中:
p:tooltip
p:columnToggler
p:notifiactionBar
p:selectOneMenu
p:autoComplete
p:confirmDialog
p:dialog
p:draggable
p:menuButton
p:selectCheckboxMenu
p:selectOneMenu
p:splitButton
有什么方法可以阻止此标记在导航后出现?
更新:此问题已被确认为 Liferay Faces 项目中的错误,并已作为 Bridge Ext 5.0.3 的一部分得到修复:FACES-3328.
说明
这个问题是由于 PrimeFaces(最初是为 webapps 设计的)和 Liferay 7.0/SennaJS/Portlets 之间的不兼容造成的。 PrimeFaces 假定它在 webapp 环境中使用,在该环境中它可以控制页面上的所有标记,因此许多使用 JavaScript 帮助呈现的组件将其标记附加到 <body>
标记。
这是 PrimeFaces 正在做的超级简化版本:
<body>
<script>
var dynDiv = document.createElement("div");
var text = document
.createTextNode("I was created dynamically via JavaScript!");
dynDiv.appendChild(text);
document.body.appendChild(dynDiv);
</script>
</body>
但是,在 portlet 环境中,portlet 只能控制 <body>
标记内的 <div>
portlet 标记。但是由于 PrimeFaces 假定一个 webapp 环境,它仍然将标记附加到 <body>
:
<body>
<div id="myPrimeFacesPortlet">
<script>
var dynDiv = document.createElement("div");
var text = document
.createTextNode("I was created dynamically via JavaScript!");
dynDiv.appendChild(text);
document.body.appendChild(dynDiv);
</script>
</div>
</body>
在 Liferay 7.0 之前,这不是问题,因为每次导航都会导致整个页面加载,并且 PrimeFaces JavaScript 创建的所有动态元素都会被破坏。现在使用 Liferay 7.0 the Single Page Application engine of SennaJS is used to make sure that only necessary parts of the page are loaded and rendered on navigation。现在,当您通过 SennaJS 离开 PrimeFaces portlet 时,所有 PrimeFaces CSS 将与 portlet <div>
一起被删除。动态元素未被删除,PrimeFaces CSS 已卸载,因此无法再隐藏它们。
解决方案
这个问题有几种可能的解决方案(我已经按照从好到坏的顺序排列):
如果组件具有
appendTo
属性,请确保将标记附加到 portlet 标记内的元素:appendTo="@this"
、appendTo="@id(#{portletNamespace})"
(对于最外层<div>
的 portlet)或appendTo="@form"
也应该工作(尽管appendTo="@root"
似乎不工作)(参见 the PF User Guide (p. 558) for more details on the "Search Expression Framework")。永久隐藏 CSS 的动态元素。为确保 CSS 不会在 SennaJS 导航中被删除,请设置
data-senna-track="permanent"
:<h:head> <!--You'll need to look at the CSS for each element (not just tooltip) to figure out what CSS classes should be hidden. --> <style id="hidePrimeFacesLeftoverMarkupWorkaroundCSS" data-senna-track="permanent"> .ui-tooltip { display: none; } </style> </h:head>