2012-08-01 55 views
0

我創建JSF2.0和RichFaces的一個測試項目。我正在試圖繪製圖表。現在,我得到了從數據庫到bean和數據表的價值。現在,當我想這個值傳遞給JavaScript varible,發現這個answer從該BalusC非常的Userful。它工作正常,但JavaScript變量在oncomplete後獲得的值=「jsonDemo('#{kpilist.json}')」。即#{kpilist.json}的值不是最新的,而是最後一個。JSF EL表達式留住老值(JSF生命週期)

我已打印#{kpilist.json}的值。如果打印出數據,則該值爲當前值。如果它在數據表之前打印,則它是最後一個值。所有的道路,因爲A4J的屬性的onComplete:eveything後AJAX執行完成,爲什麼不#{} kpilist.json顯示最新值? Richfaces和jsf組件的各種監聽器和不完整的屬性的執行順序是什麼?

我的託管Bean:

@ManagedBean(name = "kpilist") 
@ViewScoped 
public class KPIListController implements Serializable { 

    private static final long serialVersionUID = 1L; 
    boolean state = true; 
    String selectedKPIType; 
    String selectKPITime = "D"; 
    boolean renderDatatable; 
    String json; 



    public String getJson() { 
     return json;  
    } 


    public boolean isRenderDatatable() { 
     return renderDatatable; 
    } 

    public void setRenderDatatable(boolean renderDatatable) { 
     this.renderDatatable = renderDatatable; 
    } 

    public boolean isState() { 
     return state; 
    } 

    public List<String> showViewList() { 
     Logger.getLogger(KPIListController.class.getName()).warning("Show view List:"); 
     KPIDAO kpiDAO = new KPIDAO(); 
     try { 
      Logger.getLogger(KPIListController.class.getName()).info("Into show view List ---select One"); 
      return kpiDAO.showViewList(selectKPITime); 
     } catch (SQLException ex) { 
      ex.printStackTrace(); 
      Logger.getLogger(KPIListController.class.getName()).log(Level.SEVERE, null, ex); 
      return null; 
     } 
    } 

    public void setState(boolean state) { 
     this.state = state; 
    } 

    public String getSelectedKPIType() { 
     return selectedKPIType; 
    } 

    public void setSelectedKPIType(String selectedKPIType) { 
     this.selectedKPIType = selectedKPIType; 
    } 

    public String getSelectKPITime() { 
     return selectKPITime; 
    } 

    public void setSelectKPITime(String selectKPITime) { 
     this.selectKPITime = selectKPITime; 
    } 

    public List<KPI> getKPI() { 
     Logger.getLogger(KPIListController.class.getName()).warning("Get KPI Values:"); 
     KPIDAO kpiDAO = new KPIDAO();   
     List<KPI> kpiList = new ArrayList<KPI>(); 

     try { 
      kpiList = kpiDAO.getKPI(selectedKPIType); 
      Logger.getLogger(KPIListController.class.getName()).warning("KPI List:"+kpiList.size());    

     } catch (SQLException ex) { 
      ex.printStackTrace(); 
      return null; 
     } 
     Gson gson = new Gson(); 
     json= gson.toJson(kpiList); 
     return kpiList; 
    } 

    public void resetFormValues() {  
     Logger.getLogger(KPIListController.class.getName()).warning("Reset form:"); 
     selectedKPIType = "--"; 
    } 
} 

筆者認爲:

<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:rich="http://richfaces.org/rich" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:a4j="http://richfaces.org/a4j" 
     xmlns:ui="http://java.sun.com/jsf/facelets" 
     xmlns:c="http://java.sun.com/jsp/jstl/core"> 
    <h:head> 

    </h:head> 
    <h:body> 
     <ui:composition template="/contentTemplate.xhtml"> 
      <ui:define name="windowTitle">KPI Index</ui:define> 
      <ui:define name="content" > 

       <h:outputScript name="js/graphics/jquery.js"/> 
       <h:outputStylesheet name="/css/jquery-ui-1.8.22.custom.css"/> 
       <h:outputScript name="js/graphics/jquery-ui-1.8.22.custom.min.js"/> 
       <h:outputScript name="js/OpenLayers/OpenLayers.js"/> 

       <h:outputScript name="js/graphics/raphael-min.js"/> 
       <h:outputScript name="js/graphics/canvg.js"/> 
       <h:outputScript name="js/graphics/paths.js"/> 
       <h:outputScript name="js/graphics/draw.js"/> 

       <h:form id="ins_sel_form"> 
        <h:outputText value="KPI TIME FRAME"/> 
        <h:selectOneRadio value="#{kpilist.selectKPITime}" > 
         <f:selectItem itemLabel="DAILY" itemValue="D" /> 
         <f:selectItem itemLabel="WEEKLY" itemValue="W" /> 
         <f:selectItem itemLabel="LAST WEEK" itemValue="LW" />  
         <a4j:ajax event="change" render="ins_sel_form:selectOnemenu dataPnl" listener="#{kpilist.resetFormValues()}" /> 
        </h:selectOneRadio> 

        <h:outputText value="Major KPI Type"/> 
        <h:selectOneMenu id="selectOnemenu" value="#{kpilist.selectedKPIType}" > 
         <f:selectItem itemValue="--" itemLabel="--"></f:selectItem> 
         <f:selectItems itemValue="#{item.toString()}" var="item" itemLabel="#{item.toString()}" value="#{kpilist.showViewList()}"/> 
         <a4j:ajax event="change" render="dataPnl" oncomplete="jsonDemo('#{kpilist.json}')" /> 
        </h:selectOneMenu> 

        <h:outputText value="Show/Hide Map"/> 

       </h:form> 
       <rich:panel id ="dataPnl"> 

         <rich:dataTable id="kpiValueTable" value="#{kpilist.KPI}" var="kpi" style="width:100%" rows="20" rendered="#{kpilist.selectedKPIType!=null and kpilist.selectedKPIType !='--' }" >        

          <rich:column> 
           <f:facet name="header" > 
            <h:outputText value ="Value"></h:outputText> 
           </f:facet> 
           <h:outputText value="#{kpi.KPIValue}"></h:outputText> 
          </rich:column> 

         </rich:dataTable> 
        JSON String : <h:outputText id="json" value ="#{kpilist.json}"/> 
         <center><rich:dataScroller for="kpiValueTable" rendered="#{kpilist.selectedKPIType!=null and kpilist.selectedKPIType!='--'}"/></center> 
        </rich:panel> 

       <rich:panel id="map" style="display: none;"> 
       </rich:panel> 


      </ui:define> 
     </ui:composition> 
    </h:body> 
</html> 

的Javascript:

function jsonDemo(jsonString){ 

    console.log("Chart data already retrieved: " + jsonString); 
    var data = $.parseJSON(jsonString);  
    $.each(data,function(i,val){ 
     console.log("The value of i: "+i+" The val: "+val.NCELLCLUSTER); 
    }); 

} 

回答

1

oncomplete中的EL表達式是在JSF(因此,在初始HTTP請求)生成HTML/JS代碼時評估的。如你所期望的那樣,在目前oncomplete在JS中執行時沒有對它進行評估。這不是評估EL表達式的網頁瀏覽器,而是網絡服務器。 oncomplete正好在render之後執行。使用HTTP流量調試器和JS調試器(在Chrome/IE9/Firebug中按F12),您可以輕鬆跟蹤它。

有幾種可能性,以解決這個問題:

  1. 只需調用jQuery的一個$.get()$.getJSON(),做一個normal servlet這項工作代替,或更好的,一個JAX-RS web服務。

    function jsonDemo() { 
        $.getJSON("servletURL", function(jsonData) { 
         // ... 
        }); 
    } 
    
  2. 一些<h:outputScript>你通過AJAX渲染/更新更換oncomplete

    <a4j:ajax ... render="json" /> 
    ... 
    <h:panelGroup id="json"> 
        <h:outputScript rendered="#{not empty bean.json}">jsonDemo(#{bean.json});</h:outputScript> 
    </h:panelGroup> 
    

無關到具體的問題,你存在的方式概念性的錯誤,以繞過JSON數據。你字符串化它,而傳遞作爲參數,像這樣jsonDemo('#{kpilist.json}')然後你解析JSON之後使用$.parseJSON()。這沒有意義。刪除周圍的那些說法像singlequotes這樣jsonDemo(#{kpilist.json}),然後你不需要那麼$.parseJSON()行了。然後,這個數據已經 JSON格式。

0

嘗試從a4j:ajax更改爲f:ajax

不確定a4j:ajax是否適用於普通的JSF組件

+0

是它的工作原理嗯..但不知道的執行順序的它像的onComplete組件,渲染等。 – kinkajou 2012-08-01 14:25:17

+0

看看這個BalucS的例子,注意''show ='showProgress'''showProgress'實現,http://stackoverflow.com/a/7044332/617373 – Daniel 2012-08-01 14:31:52