2013-10-23 29 views
0

我在Tomcat6上使用JSF 2.1和el2.2庫。JSF 2.1 - 動態UIComponents和鏈接

我已經創建了一個模板佈局,其中包含所有頁面通用的標題,菜單欄和頁腳,僅更改了內容。每個部分都有自己的div標籤。一切工作正常,菜單欄鏈接使用faces-config導航規則正確導航到新頁面。

我現在已經創建了一個包含動態創建的UIComponent的內容頁面。視圖呈現時,帶有一個項目的panelgrid正確顯示,但所有菜單項不再有效!

如果我從xhtml中刪除panelgrid標記並刷新,那麼菜單項再次正確工作。在這種情況下,生成的HTML中唯一的區別是panelgrid的table標籤是否存在。

在下面的例子中,我將它分解爲一個HtmlPanelGrid和一個孩子。

我的Bean :(所有的BaseBean都是實現Serializable的)。

package org.gwl.chart; 

import java.util.List; 

import javax.annotation.PostConstruct; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.SessionScoped; 
import javax.faces.component.html.HtmlOutputLabel; 
import javax.faces.component.html.HtmlPanelGrid; 

import com.praxism.iims.web.BaseBean; 

@ManagedBean 
@SessionScoped 
public class DashBacker extends BaseBean { 

    private static final long serialVersionUID = -894246439580172432L; 

    HtmlPanelGrid _dash; 

    public DashBacker() { 
    } 

    @PostConstruct 
    public void init() { 
     _dash = new HtmlPanelGrid(); 
     _dash.setColumns(3); 
     _dash.setId("dashboard"); 

     HtmlOutputLabel label1 = new HtmlOutputLabel(); 
     label1.setId("label1"); 
     label1.setValue("Label 1"); 
     _dash.getChildren().add(label1); 
    } 

    public HtmlPanelGrid getDash() { 
     return _dash; 
    } 
} 

我的內容XHTML

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:p="http://primefaces.org/ui" 
    xmlns:iims-chart="http://java.sun.com/jsf/composite/components/chart"> 
    <ui:composition>  
     <h:outputText styleClass="h1" value="#{msgs_dash.heading}"/> 
     <h:messages errorClass="errorMessage" infoClass="infoMessage" warnClass="warnMessage"/> 
     <h:panelGrid binding="#{dashBacker.dash}" /> 
    </ui:composition> 
</html> 

我的菜單欄XHTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:p="http://primefaces.org/ui"> 
    <ui:composition> 
     <h:form id="menuBarFrm" styleClass="my-menubar"> 
      <p:menubar> 
       <p:menuitem rendered="#{request.isUserInRole('user')}" value="Home" action="home"/> 
       <p:submenu rendered="#{request.isUserInRole('user')}" label="Help"> 
        <p:menuitem rendered="#{request.isUserInRole('user')}" value="About" action="about"/> 
       </p:submenu> 
      </p:menubar> 
     </h:form> 
    </ui:composition> 
</html> 

最後,我的佈局模板

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:ui="http://java.sun.com/jsf/facelets" 
     xmlns:h="http://java.sun.com/jsf/html"> 
    <h:head> 
     <title><ui:insert name="windowTitle">DEFAULT_TITLE</ui:insert></title> 
    </h:head> 
    <h:body> 
     <div id="layout-header"> 
      <ui:insert name="header">No define for "header"!</ui:insert> 
     </div> 
     <div id="layout-menubar"> 
      <ui:insert name="menubar">No define for "menu"!</ui:insert> 
     </div> 
     <div id="layout-content"> 
      <div id="layout-scrollable"> 
       <div id="layout-margin"> 
        <ui:insert name="content">No define for "content"!</ui:insert> 
       </div> 
      </div> 
     </div> 
     <h:messages/> 
     <div id="layout-footer"> 
      <ui:insert name="footer">No define for "content"!</ui:insert> 
     </div> 
    </h:body> 
</html> 
+0

當您點擊主頁時,它是否正確重定向,加載後菜單項是否可以工作 – BholaVishwakarma

+0

如果我要通過顯式URL瀏覽幫助/關於頁面,那麼菜單項會起作用,我可以重新瀏覽到那裏或瀏覽到主頁。 僅當呈現Home時,菜單纔會停止工作。 (它對鼠標懸停和子菜單彈出,但沒有鏈接工作) –

回答

0

不能存放在什麼比更高的組件請求sc OPE。

+0

我只移動到SessionScoped,因爲我原來的ViewScoped導致HtmlPanelGrid的NonSerializableException。我從未考慮過縮小範圍。 RequestScoped的作品。 任何解釋它影響菜單欄鏈接的奇怪行爲,特別是當生成的HTML是相同的? –

+0

這需要很多解釋。只要說它被規範所禁止(至少在2.2)就足夠了,因此是無證的行爲。通過在會話中的JSF視圖樹中存儲對任何內容的引用,您還會在會話中隱式地存儲對ViewRoot的引用(會根據每個請求重新創建引用),從而導致內存泄漏和大量意外副作用。 爲什麼這種奇怪的行爲?由於JSF無法在回發中正確地恢復視圖(因此),因此很難說沒有調試就發生了什麼問題。但是,錯誤的原因很明顯。 – Freddy