2015-01-02 39 views
0

我的項目是一個類似於JasperReport的動態報告應用程序,並且使用JSF 2.2.7(Mojara)和primefaces 5.0。當用戶登錄時,他/她只會看到從數據庫動態加載的分配給他/她的報告。除了當他們選擇一個報告時,其他一切都正常工作,該頁面不會加載整個報告,直到第二次點擊。動態JSF/Primefaces差加載

我的問題是報告沒有正確加載,直到第二次點擊。這是我的代碼。

@Named(value = "userController") 
@SessionScoped 
public class ReportUserController implements Serializable { 

private HtmlPanelGroup panelGroup; // with getter and setter 

@PostConstruct 
public void init() { 
    values = new ArrayList<>(); 
    // Retrieve user's details and reports here 

    MenuModel model = new DefaultMenuModel(); 
    Application application = FacesContext.getCurrentInstance().getApplication(); 
    panelGroup = (HtmlPanelGroup) application.createComponent(HtmlPanelGroup.COMPONENT_TYPE); 
    PanelGrid panelGrid = (PanelGrid) application.createComponent(PanelGrid.COMPONENT_TYPE); 
    panelGrid.setColumns(2); 

    // Retrieve reports for d group the logged-in user belong 
    List<Report> repts = setupController.getExistingReports(); 

    DefaultSubMenu reports = new DefaultSubMenu("Reports"); 
    for (Report rep : repts) { 
     DefaultMenuItem menuItem = new DefaultMenuItem(rep.getReportName()); 
     menuItem.setId(rep.getReportName().replaceAll("\\s+", "")); 
     menuItem.setAjax(true); 
     menuItem.setUpdate(":reportForm"); 
     menuItem.setProcess("@form"); 
     menuItem.setCommand("#{userController.loadReport(" + rep.getId() + ")}"); 
     reports.addElement(menuItem); 
     reports.addElement(new DefaultSeparator()); 

    } 
    model.addElement(reports); 
    Menubar menubar = (Menubar) application.createComponent(Menubar.COMPONENT_TYPE); 
    menubar.setModel(model); 

    panelGroup.getChildren().add(menubar); 

} 

public void loadReport(Long id) { 

    selectedReport = reportFacade.find(id); 
    if (parameters != null) { 
     parameters.clear(); 
    } 

    if (values != null) { 
     values.clear(); 
    } 

    queryColumns = selectedReport.getColumns(); 

    queryParams = selectedReport.getReportParameters(); 
    query = selectedReport.getReportQuery(); 

    // This method is called to build the components of the page to be rendered dynamically. 
    // And it's every time a new report is selected 
    buildPage(); 

} 

} 

這裏是在同一個類中的方法buildPage()。 (請原諒它的一個愚蠢的長碼)

public void buildPage() { 

    Application application = FacesContext.getCurrentInstance().getApplication(); 
    reportPanelGroup = (HtmlPanelGroup) application.createComponent(HtmlPanelGroup.COMPONENT_TYPE); 
    PanelGrid panelGrid = (PanelGrid) application.createComponent(PanelGrid.COMPONENT_TYPE); 
    panelGrid.setColumns(2); 

    for (ReportParameter param : queryParams) { 

     String parameterLabel = param.getLabel(); 
     String componentType = param.getComponentType(); 
     String calendarPattern = param.getCalendarPattern(); 
     boolean required = param.isRequired(); 
     boolean userProperty = param.isUserProperty(); 
     String queryPosition = param.getQueryPosition(); 
     String sqlDatePattern = param.getSqlDatePattern(); 
     String dataType = param.getDataType(); 
     String userPropertyName = param.getUserPropertyName(); 
     List<DropDown> dropDowns = param.getDropDowns(); 

     if ((userProperty)) { 
      // Retrieve some info from the logged-in user    
     } else { 

      OutputLabel label = (OutputLabel) application.createComponent(OutputLabel.COMPONENT_TYPE); 

      label.setId(parameterLabel.replaceAll("\\s+", "") + "label"); 
      label.setValue(parameterLabel + ":"); 

      if (componentType.equalsIgnoreCase("Calendar")) { 
       Calendar cal = (Calendar) application.createComponent(Calendar.COMPONENT_TYPE); 

       cal.setId(parameterLabel.replaceAll("\\s+", "")); 
       cal.setShowButtonPanel(true); 
       cal.setPattern(calendarPattern); 
       cal.setRequired(required); 

       cal.setValueExpression("value", 
         getExpressionFactory() 
         .createValueExpression(getELContext(), "#{userController.parameters['" 
           + queryPosition.trim() + "']}", Date.class)); 

       label.setFor(parameterLabel.replaceAll("\\s+", "")); 
       panelGrid.getChildren().add(label); 

       panelGrid.getChildren().add(cal); 

      } else if (componentType.equalsIgnoreCase("TextField")) { 
       InputText input = (InputText) application.createComponent(InputText.COMPONENT_TYPE); 
       input.setRequired(required); 
       input.setId(parameterLabel.replaceAll("\\s+", "")); 

       input.setValueExpression("value", 
         getExpressionFactory() 
         .createValueExpression(getELContext(), "#{userController.parameters['" 
           + queryPosition.trim() + "']}", String.class)); 

       label.setFor(parameterLabel.replaceAll("\\s+", "")); 
       panelGrid.getChildren().add(label); 

       panelGrid.getChildren().add(input); 
      } else if (componentType.equalsIgnoreCase("DropDown")) { 

       SelectOneMenu selectOneMenu = (SelectOneMenu) application.createComponent(SelectOneMenu.COMPONENT_TYPE); 
       UISelectItems selectItems = (UISelectItems) application.createComponent(UISelectItems.COMPONENT_TYPE); 
       selectOneMenu.setRequired(required); 
       selectOneMenu.setId(parameterLabel.replaceAll("\\s+", "")); 

       selectItems.setId(parameterLabel.replaceAll("\\s+", "") + "selectItems"); 

       List<SelectItem> items = new ArrayList<>(); 

       items.add(new SelectItem("", "Select...")); 
       if (dropDowns != null && !dropDowns.isEmpty()) { 
        for (DropDown d : dropDowns) { 
         items.add(new SelectItem(d.getValue(), d.getLabel())); 
        } 
       } 

       selectItems.setValue(items); 
       selectOneMenu.getChildren().add(selectItems); 

       selectOneMenu.setValueExpression("value", 
         getExpressionFactory() 
         .createValueExpression(getELContext(), "#{userController.parameters['" 
           + queryPosition.trim() + "']}", String.class)); 

       label.setFor(parameterLabel.replaceAll("\\s+", "")); 
       panelGrid.getChildren().add(label); 

       panelGrid.getChildren().add(selectOneMenu); 

      } 
     } 
    } 
    reportPanelGroup.getChildren().add(panelGrid); 

    HtmlCommandButton searchBtn = (HtmlCommandButton) application.createComponent(HtmlCommandButton.COMPONENT_TYPE); 
    searchBtn.setId("searchBtnID"); 
    searchBtn.setValue("Search"); 
    //searchBtn.setIcon("icon ui-icon-search"); 
    //searchBtn.setAjax(false); 

    ExpressionFactory ef = getApplication().getExpressionFactory(); 
    MethodExpression performSearch = ef.createMethodExpression(getELContext(), 
      "#{userController.performSearch}", null, new Class[]{ActionEvent.class}); 
    MethodExpressionActionListener meal = new MethodExpressionActionListener(performSearch); 
    searchBtn.addActionListener(meal); 
    searchBtn.setType("submit"); 

    //searchForm.getChildren().add(searchBtn); 
    reportPanelGroup.getChildren().add(searchBtn); 

    Spacer spacer = (Spacer) application.createComponent(Spacer.COMPONENT_TYPE); 
    spacer.setHeight("30"); 
    reportPanelGroup.getChildren().add(spacer); 

    HtmlForm downloadForm = (HtmlForm) application.createComponent(HtmlForm.COMPONENT_TYPE); 
    downloadForm.setId("downloadForm"); 

    CommandLink downloadBtn = (CommandLink) application.createComponent(CommandLink.COMPONENT_TYPE); 
    downloadBtn.setId("downloadBtnID"); 
    downloadBtn.setValue("Test Download"); 
    //downloadBtn.setIcon("icon ui-icon-search"); 
    downloadBtn.setAjax(false); 

    String reportName = this.selectedReport.getReportName().trim().replaceAll("\\s+", "").trim(); 

    MethodExpression downloadAnyReport = ef.createMethodExpression(getELContext(), 
      "#{userController.downloadAnyReport(userController.values, " 
      + "userController.headings, '" + reportName + "')}", null, // Replace report name 
      new Class[]{List.class, Collection.class, String.class}); 
    downloadBtn.setType("submit"); 
    downloadBtn.setActionExpression(downloadAnyReport); 

    downloadForm.getChildren().add(downloadBtn); 
    reportPanelGroup.getChildren().add(downloadForm); 

    DataTable dynamicTable = (DataTable) application.createComponent(DataTable.COMPONENT_TYPE); 
    dynamicTable.setValueExpression("value", getExpressionFactory() 
      .createValueExpression(getELContext(), "#{userController.values}", List.class)); 
    dynamicTable.setVar("val"); 
    dynamicTable.setRows(20); 

    List cols = new ArrayList<>(); 

    for (int i = 0; i < queryColumns.size(); i++) { 
     Column col = (Column) application.createComponent(Column.COMPONENT_TYPE); 
     col.setHeaderText(queryColumns.get(i).getPrefferedName()); 
     if (queryColumns.get(i).isLink()) { 
      HtmlForm linkForm = (HtmlForm) application.createComponent(HtmlForm.COMPONENT_TYPE); 
      linkForm.setId("linkForm"); 
      CommandLink link = (CommandLink)  application.createComponent(CommandLink.COMPONENT_TYPE); 

      if (queryColumns.get(i).isDataMasked()) { 
       link.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{userController.maskStringValue(val[" + i + "]," + queryColumns.get(i).getLeftDigit() + "," + queryColumns.get(i).getRightDigit() + ")}", String.class)); 
      } else { 
       link.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{val[" + i + "]}", String.class)); 
      } 

      link.setStyle("text-decoration: underline; color: blue;"); 
      MethodExpression action = ef.createMethodExpression(getELContext(), 
        "customizeColumns?faces-redirect=true", null, new Class[]{String.class}); 
      link.setAjax(false); 
      link.setActionExpression(action); 
      linkForm.getChildren().add(link); 
      col.getChildren().add(linkForm); 
     } else { 
      HtmlOutputText out = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE); 
      if (queryColumns.get(i).getFormatAs() != null && queryColumns.get(i).getFormatAs().equals("Amount")) { 
       out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{userController.formatAsAmount(val[" + i + "])}", String.class)); 
      } else if (queryColumns.get(i).getFormatAs() != null && queryColumns.get(i).getFormatAs().equals("Number")) { 
       out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{userController.formatAsNumber(val[" + i + "])}", String.class)); 
      } else if (queryColumns.get(i).isDataMasked()) { 
       out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{userController.maskStringValue(val[" + i + "]," + queryColumns.get(i).getLeftDigit() + "," + queryColumns.get(i).getRightDigit() + ")}", String.class)); 
      } else { 
       out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{val[" + i + "]}", String.class)); 
      } 

      col.getChildren().add(out); 
     } 
     cols.add(col); 
    } 

    dynamicTable.setColumns(cols); //renderReport 
    dynamicTable.setValueExpression("rendered", getExpressionFactory() 
      .createValueExpression(getELContext(), "#{userController.values.size() > 0}",  Boolean.class)); 

    dynamicTable.setPaginator(true); 
    dynamicTable.setRowsPerPageTemplate("20,50,100"); 

    reportPanelGroup.getChildren().add(dynamicTable); 

} 

這裏是我的網頁:

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets" 
      template="./usersTemplate.xhtml" 
      xmlns:h="http://xmlns.jcp.org/jsf/html" 
      xmlns:p="http://primefaces.org/ui" 
      xmlns="http://www.w3.org/1999/xhtml"> 

<ui:define name="usersTitle"> 
    usersTitle 
</ui:define> 

<ui:define name="usersContent"> 
    <div class="container-fluid"> 
     <p:growl id="growl" life="3000" sticky="true"/> 
     <h:form id="menuForm"> 
      <!-- This panelGroup is for the menubar of reports --> 
      <h:panelGroup binding="#{userController.panelGroup}"/> 
     </h:form> 
     <h:form id="reportForm"> 
      <!-- This panelGroup is to show the components and datatable of the selected report -->    
      <h:panelGroup id="reportPanel" binding="#{userController.reportPanelGroup}"/> 
     </h:form> 
    </div> 
</ui:define> 

請讓我再說一遍,一切只是當工作正常我從菜單欄中的報告列表中選擇一個報告,頁面不會更新,直到第二次點擊,我嘗試了整頁提交以及Ajax。請我非常感謝任何可以幫助你的幫助。提前致謝。

回答

0

對於未來可能有類似問題的其他人,請列舉我最終解決的解決方案,該解決方案非常適用。我在頁面上添加了一個<p:commandButton/>,其中rendered屬性與所選報告的組件切換。然後,我添加了一個JavaScript方法,在ajax調用menubarmenuItemsoncomplete屬性之後觸發點擊commandButton。下面是代碼snipets:

// JavaScript:

function clickAgain(){ 
     document.getElementById('reportForm:refreshBtn').click(); 
    } 

// I added the button to my page:

...

<h:form id="reportForm"> 
      <p:commandButton value=" Load #{userController.selectedReport.reportName}" 
          icon="ui-icon-refresh" rendered="#{!userController.renderReport}" 
          id="refreshBtn"> 
       <p:ajax update="@form" listener="#{userController.changeRender()}"/> 
      </p:commandButton> 
      <h:panelGroup id="reportPanel" binding="#{userController.reportPanelGroup}" 
          rendered="#{userController.renderReport}"/> 
</h:form> 

神奇的是,用戶不會看到該按鈕時,JavaScript函數的每一個選擇之後調用菜單項和這個重新加載頁面使按鈕消失,我的報告正確加載。謝謝