jsf - 在 Liferay 7.0 中导航后仍保留 PrimeFaces 标记
问题描述
我注意到,当我通过 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 只能控制标记<div>
内的 portlet 标记<body>
。但是由于 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中,SennaJS 的单页应用程序引擎用于确保仅加载页面的必要部分并在导航上呈现。现在,当您通过 SennaJS 离开 PrimeFaces portlet 时,所有 PrimeFaces CSS 将与 portlet 一起被删除<div>
。动态元素不会被删除,并且 PrimeFaces CSS 被卸载,因此它不能再隐藏它们。
解决方案
这个问题有几种可能的解决方案(我已经从最好到最坏对它们进行了排序):
如果组件具有
appendTo
属性,请确保将标记附加到 portlet 标记内的元素:appendTo="@this"
,appendTo="@id(#{portletNamespace})"
(对于<div>
portlet 的最外层)或者appendTo="@form"
也应该可以工作(尽管appendTo="@root"
似乎不起作用)(请参阅PF 用户指南 (p. 558)有关“搜索表达式框架”的更多详细信息)。使用 CSS 永久隐藏动态元素。为确保在 SennaJS 导航中不删除 CSS,请设置
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>
更多信息:
推荐阅读
- javascript - rails 在本地工作,但在 heroku 上服务器 statut 304
- reactjs - 如何为使用的数组设置初始/默认值
? - python - 无法在 DJANGO 中完成基于 Unittest 类的视图
- c# - CreateWebHostBuilder 的 C# Lambda 表达式
- ajax - 第二次触发 JQuery Ajax 时,数据未绑定到 vuejs2,尽管 Vue 对象中的数据更新
- adb - 是否可以将应用程序中的复制/粘贴/输入(例如密码)复制到 Oculus Quest 头戴设备中?
- javascript - 未处理的拒绝(错误):预期未定义为 GraphQL 模式
- javascript - 在另一个文件中触发 https 请求时如何将对象返回给客户端?
- python - 如何解决,PermissionError: [Errno 13] Permission denied: 'test.from'
- android - 如果用户已经登录,则跳过登录屏幕