【问题标题】:Primefaces multiple dynamic content panels to be displayedPrimefaces 显示多个动态内容面板
【发布时间】:2013-01-25 08:37:27
【问题描述】:

我正在尝试在我的 Web 应用程序中创建一种简单的可定制新闻视图页面,例如 Google's one,但要简单得多,带有框架。每个框架对象都只是有他的标题和一个要作为其内容添加的 url。

我正在使用 JSF 和 primefaces,它们都是最新版本。因此,我的支持 bean,即 @ViewScoped,可以访问存储在 @SessionScoped bean 中的登录用户,并且该用户已加载相应的帧。

当我尝试在 @ViewScoped bean 上迭代它时,问题就来了,因为我发现这样做的唯一方法是使用 c:forEach 标记。我就是这样做的:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:form>
    <p:panel header="Noticias">
        <h:panelGrid columns="#{fn:length(navegableHomeManager._UserFrames)}"
            width="100%">
            <c:forEach var="frame" items="#{navegableHomeManager._UserFrames}">
                <p:column>
                    <p:panel header="#{frame._Name}" closable="true"
                        style="width:95%;height:500px;" id="#{frame._Name}">
                        <p:ajax event="close"
                            listener="#{navegableHomeManager.actionFrameClosed}" />
                        <ui:include src="#{frame._Path}" />
                    </p:panel>
                </p:column>
            </c:forEach>
        </h:panelGrid>
    </p:panel>
</h:form>

该迭代显然不适用于navegableHomeManager bean,因为它是@ViewScoped。所以 bean 将在每次迭代中重建。我达到的解决方案在navegableHomeManagerloggedBean 之间使用了另一个@SessionScoped bean,这样帧就存储在那里,我可以在迭代中正确访问它们。这与上面的代码一起工作。

但是我不认为每次我想以这种方式迭代时都必须使用 @SessionScoped bean(为每个案例创建一个特定的 bean)。 这就是我尝试使用组件来避免迭代的原因。

<p:dataGrid columns="#{fn:length(navegableHomeManager._UserFrames)}"
            value="#{navegableHomeManager._UserFrames}" var="frame">
    <p:column>
        <p:panel header="#{frame._Name}" closable="true"
                    style="width:95%;height:500px;">
            <p:ajax event="close"
                        listener="#{navegableHomeManager.actionFrameClosed}" />
            <ui:include src="#{frame._Path}" />
        </p:panel>
    </p:column>
</p:dataGrid>

当bean是@ViewScoped@SessionScoped时它也不起作用,因为即使设置了框架属性,ui:include标签已经构建了没有目标路径,所以我无法渲染目的地路径动态。我认为,由于ui:includec:forEach 同时应用,因此使用c:forEach 标签确实是解决此问题的唯一方法。

集思广益。

更新

在这里我发布更多 xhtml 代码来帮助理解上下文。新的页面被集成到模板中。这就是目标页面(/system/home/index.xhtml):

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
template="/templates/general_template.xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">

<ui:define name="metadata">
    <f:event type="preRenderView"
        listener="#{navegableHomeManager.initialize}" />
</ui:define>

<ui:define name="general_content">
    <ui:include src="/system/home/home_view.xhtml" />
</ui:define>

这也是我尝试过的方式,但没有使c:forEach 标记起作用:

<context-param>
    <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
    <param-value>/system/home/index.xhtml</param-value>
</context-param>

这就是支持 bean 标头:

@ManagedBean
@ViewScoped
@URLMapping(id = "home", pattern = "/home", viewId = "/system/home/index.xhtml")
public class NavegableHomeManager extends SystemNavegable {

/**
 * 
 */
private static final long serialVersionUID = 6239319842919211716L;

@ManagedProperty(value = "#{loggedBean}")
private LoggedBean _LoggedBean;

//More stuff

【问题讨论】:

    标签: jsf jsf-2 primefaces


    【解决方案1】:

    坚持&lt;c:forEach&gt;。它可以完成您正在寻找的工作。 &lt;ui:include&gt; 在视图构建期间运行,因此迭代标记也应该在视图构建期间运行。

    至于@ViewScoped bean 问题,您有两个选择:

    1. 关闭特定视图的部分状态保存:

      <context-param>
          <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
          <param-value>/news.xhtml</param-value>
      </context-param>
      
    2. 将其更改为 @RequestScoped bean 并使用 &lt;f:param&gt;@ManagedProperty 通过请求参数跨回发维护状态。

    如果 JSF 2.2 可用,还有第三种选择:只需升级到 JSF 2.2。他们已经修复了视图范围 bean 和部分状态保存中的鸡蛋问题。

    【讨论】:

    • 感谢您的回答。出于某种原因,基于context-param 的解决方案不起作用。 navegableHomeManager 现在直接从loggedBean 恢复帧,但forEach 标记没有进行迭代,即使#{fn:length(navegableHomeManager._UserFrames)} 返回1。 bean 仅在我访问页面时构建,这是正确的。我也无法升级到 JSF 2.2,因为没有稳定的版本,我不能 100% 信任它。
    • 至于上下文参数,显然你指定了错误的视图 ID(注意:视图 ID 不是 URL,它是物理文件的上下文相关路径,所以即使你映射了 JSF 的东西在 *.jsf 上,您仍应在视图 ID 中使用 .xhtml)。至于其余部分,抱歉,根据目前提供的信息很难理解问题。
    • 我更新了问题,添加了更多我的代码 BalusC。希望它会有所帮助。
    • preRenderView 事件不会在视图构建期间运行。使用 postconstruct。
    猜你喜欢
    • 2014-01-28
    • 2014-12-12
    • 1970-01-01
    • 2018-07-09
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    相关资源
    最近更新 更多