【问题标题】:Partial Page Rendering using Primefaces - update is fired too early when using <ui:include>?使用 Primefaces 的部分页面渲染 - 使用 <ui:include> 时过早触发更新?
【发布时间】:2012-08-23 09:30:30
【问题描述】:

我有一个使用 Primefaces 3.3.1(在 Glassfish 3.0.1 上运行)的 Web 应用程序,用户可以在其中在菜单中选择所需的内容。由于只有部分页面要刷新,所以我想通过 AJAX 使用部分页面刷新。存储URL的方法在commandButton的actionListener-attribute中提供,而需要更新的组件的id在commandButton的update-attribute中提供。

我将首先附上我的示例源代码 - 我从另一个有关 PPR 的线程中获得,但已确认可以正常工作:

ma​​in.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets">

    <h:body>
        <h:panelGroup id="content" layout="block">
            <ui:include src="#{navBean.activePage}" />
        </h:panelGroup>

        <h:form>
            <p:commandButton value="next"
                             actionListener="#{navBean.next}" 
                             update=":content" />
            <p:commandButton value="back"
                             actionListener="#{navBean.back}" 
                             update=":content" />
        </h:form>
    </h:body>
</html>

NavBean

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;

@ManagedBean
@SessionScoped
public class NavBean {

    private String activePage = "somepage.xhtml";


    public String getActivePage() {
        return activePage;
    }


    public void setActivePage(String activePage) {
        this.activePage = activePage;
    }


    public void next(ActionEvent e) {
        this.setActivePage("someotherpage.xhtml");
    }


    public void back(ActionEvent e) {
        this.setActivePage("somepage.xhtml");
    }
}

示例包含页面(“somepage.xhtml”)

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets">

    <h2>Just some content for testing purposes</h2>

</ui:composition>

现在,问题是,getActivePage总是setActivePage 之前被调用 - 这显然是一个问题,因为必须单击按钮两次才能获取新内容。

我觉得我在这里遗漏了一些重要的东西,但是在 Google/stackoverflow 上搜索并没有带来任何适用的结果。

更新:用action替换actionListener不起作用(我当然相应地更改了被调用方法的输入参数)。

正如 erencan 在下面的评论中所建议的,我将 &lt;ui:include&gt; 替换为 &lt;h:outputText&gt;,只显示一个字符串:

<h:outputText value="#{navBean.activePage}" />

与我的预期相反,这工作正常。那么为什么&lt;h:outputText&gt; 有效,而&lt;ui:include&gt; 无效呢?使用前者不是一个选项,因为我想使用 JSF 模板功能。

【问题讨论】:

  • 就我而言,pa 必须由服务器解释。所以只改变属性值是行不通的。你应该刷新页面。或者您可以将页面内容呈现为字符串。
  • 希望我正确理解了您的评论 - 您是否偶然发现了我没有包含所包含文件的来源的事实? (即“somepage.xhtml”和“someotherpage.xhtml”)我将在一分钟内包含这些示例......我还将尝试将页面内容呈现为字符串,尽管我怀疑这会解决问题。然而,刷新页面不是一种选择,因为这是我试图通过使用 PPR 来避免的。
  • 我声称通过使用 ajax 更改 ui:include 的值不会影响实际页面。我认为您应该呈现实际页面而不是页面名称。我发现与您类似的问题。我希望它有帮助。 stackoverflow.com/questions/7746221/…
  • 谢谢@erencan!在您链接的问题中,我找到了另一个指向此answer 的链接,指向类似问题。在对我从那里得到的源代码进行了一些定制之后,我终于让它工作了。如果您愿意,请将其作为答案发布,我会接受(否则,为了完整起见,我将自己回答问题)。
  • 不客气。最好写一个答案。您有机会发送完整的代码以解决更多问题。

标签: ajax jsf primefaces


【解决方案1】:

我终于解决了这个问题,使用this 回答了一个类似的问题。我将在这里发布我的代码,以便遇到相同问题的任何人都可以使用它:

ma​​in.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">

    <h:body>
        <h:panelGroup id="header" layout="block">
            <h1>Header</h1>
        </h:panelGroup>
        <h:panelGroup id="menu" layout="block">
            <h:form>
                <f:ajax render=":content">
                    <p:commandButton value="next" action="#{navBean.next}" process="@this"/>            
                    <p:commandButton value="back" action="#{navBean.back}" process="@this"/>
                </f:ajax>
            </h:form>
        </h:panelGroup>
        <h:panelGroup id="content" layout="block">
            <h:panelGroup rendered="#{navBean.activePage == 'firstAjax'}">
                <ui:include src="firstAjax.xhtml" />
            </h:panelGroup>
            <h:panelGroup rendered="#{navBean.activePage == 'lastAjax'}">
                <ui:include src="lastAjax.xhtml" />
            </h:panelGroup>
        </h:panelGroup>
    </h:body>
</html>

这段代码基本上取自链接的答案,但我不得不稍微调整一下(基本上,将&lt;h:commandLink&gt; 更改为&lt;p:commandButton&gt;,因为前者不知何故没有调用action 中提供的方法)。

NavBean.java

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class NavBean {

    private String activePage = "firstAjax";


    public String getActivePage() {
        return activePage;
    }


    public void setActivePage(String activePage) {
        this.activePage = activePage;
    }


    public void next() {
        this.setActivePage("lastAjax");
    }


    public void back() {
        this.setActivePage("firstAjax");
    }
}

只是一个包含变量的标准 ManagedBean。

firstAjax.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:form>
        <h2>content...</h2>
    </h:form>
</ui:composition>

包含的 XHTML 页面。 lastAjax.xhtml 几乎一样。

【讨论】:

    猜你喜欢
    • 2011-08-14
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多