JSF El表达式保留旧值(JSF生命周期)

时间:2012-08-01 14:10:42

标签: jsf-2 richfaces page-lifecycle

我用JSF2.0和richfaces创建了一个测试项目。我想绘制图表。现在,我从数据库到bean和datatable都获得了价值。现在,当我想将此值传递给javascript varible时,发现这个来自BalusC的answer非常有用。它工作正常,但是在oncomplete =“jsonDemo('#{kpilist.json}')之后javascript变量得到的值”。即#{kpilist.json}的值不是最新的。

我打印了#{kpilist.json}的值。如果在数据表中打印,则该值为当前值。如果在数据表之前打印它是最后一个值。任何方式,因为a4j的完整属性:ajax在eveything完成后执行,为什么#{kpilist.json}不显示最新值?各种监听器的执行顺序和richfaces和jsf组件的不完整属性是什么?

My Managed 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);
    });

}

2 个答案:

答案 0 :(得分:1)

oncomplete中的EL表达式在JSF生成HTML / JS代码时进行评估(因此,在初始HTTP请求中)。当你在JS中执行oncomplete时,它似乎没有被评估。评估EL表达式的不是web浏览器,而是Web服务器。 oncomplete就在render之后执行。使用HTTP流量调试器和JS调试器(在Chrome / IE9 / Firebug中按F12),您可以轻松跟踪它。

有几种可能性来解决这个问题:

  1. 只需在jQuery中调用$.get()$.getJSON(),就可以用normal servlet来代替或更好地完成JAX-RS网络服务。

    function jsonDemo() {
        $.getJSON("servletURL", function(jsonData) {
            // ...
        });
    }
    
  2. oncomplete替换为您通过ajax呈现/更新的<h:outputScript>

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

  3. 对于具体问题,

    无关,就像传递JSON数据一样存在概念错误。你正在将它作为参数进行字符串化,如jsonDemo('#{kpilist.json}')那样,然后你使用$.parseJSON()解析JSON。这毫无意义。删除那些围绕参数的单引号,如jsonDemo(#{kpilist.json}),然后您不再需要$.parseJSON()行。然后,数据已经以JSON格式。

答案 1 :(得分:0)

尝试从a4j:ajax更改为f:ajax

不确定a4j:ajax是否适用于普通的JSF组件