【问题标题】:h:body not rerendered when using FullAjaxExceptionHandlerh:body 使用 FullAjaxExceptionHandler 时未重新渲染
【发布时间】:2017-04-05 07:29:15
【问题描述】:

我正在使用 OmniFaces FullAjaxExceptionHandler 来显示错误页面。错误页面显示正确,但这些页面的样式有问题。

我的应用程序使用的模板在 body 元素上定义了 CSS 类。这些类对于正常页面和错误页面是不同的:

普通页面:

<h:body styleClass="main-body layout-compact">

错误页面:

<h:body styleClass="exception-body error-page">

当 FullAjaxExceptionHandler 处理异常时,会执行到错误页面的转发(基于web.xml 中的&lt;error-page&gt; 机制)。显然这不会重新渲染 &lt;h:body&gt; 标签,因为在检查 HTML 输出时,我可以看到 &lt;body&gt; 标签仍然包含来自正常页面的 CSS 类(而不是错误页面的类)。

看来原来&lt;h:body&gt;的内容被替换为错误页面&lt;h:body&gt;的内容,而不是仅仅替换完整的&lt;h:body&gt;。我不知道这是否是默认的 JSF / FullAjaxExceptionHandler 行为。

有没有办法让&lt;h:body&gt; 使用正确的 CSS 类呈现?将 CSS 类从 &lt;h:body&gt; 移走不是一种选择。

【问题讨论】:

  • 当你转发到错误页面时,它不是一个ajax调用,所以你不能重新渲染。相反,您正在加载一个全新的全新错误页面。请检查转发是否正确。如果是这样,您将在 body 标记上应用正确的 CSS。
  • 转发是由FullAjaxExceptionHandler正确完成的,我不是自己做转发的。显示错误页面(在相同的 url 下)并且整个 内容被更改。然而, 标签仍然具有上一页中的 CSS 类。所以似乎body标签没有被重新渲染,而只是它的内容。我不知道这是否是标准的 JSF 行为。

标签: jsf omnifaces


【解决方案1】:

不幸的是,这是“设计使然”。 JSF 在执行 ajax 导航时不会替换整个文档,但它只会替换单个 &lt;head&gt;&lt;body&gt; 元素的子元素,而不会影响父元素。这样做是出于历史原因;较旧的 Internet Explorer 版本即不支持完全替换它们。

我自己所做的只是将样式放入&lt;main&gt; 元素中。在最终的 HTML 输出中,&lt;header&gt;&lt;footer&gt; 通常是相同的。基本上:

<html>
    <head>
        <title>...</title>
    </head>
    <body>
        <header>...</header>
        <main class="#{page.type}">...</main>
        <footer>...</footer>
    </body>
</html>

如果您确实需要修改 &lt;body class&gt;,那么最好的办法是通过嵌入在错误页面模板中的 JavaScript 来完成。

<h:outputScript rendered="#{faces.ajaxRequest}">
    document.body.className = "exception-body error-page";
</h:outputScript>

注意:#{faces} 仅在 OmniFaces 2.5 之后可用,如果您使用的是旧版本,请改用 #{facesContext.partialViewContext.ajaxRequest})。

【讨论】:

  • 再次感谢 BalusC 的启发性答案!由于在我们的案例中无法将样式从正文中移开,因此您提出的使用嵌入式 JavaScript 的解决方案非常有效!
猜你喜欢
  • 1970-01-01
  • 2022-01-06
  • 2020-10-06
  • 2011-05-15
  • 2016-12-30
  • 2013-11-01
  • 2020-05-22
  • 1970-01-01
  • 2023-01-31
相关资源
最近更新 更多