0

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

我已经打印了#{kpilist.json} 的值。如果它是在数据表之后打印的,则该值是当前的。如果它在数据表之前打印,则它是最后一个值。自从 a4j:ajax 的 oncomplete 属性在一切完成后执行以来的任何方式,为什么 #{kpilist.json} 不显示最新值?Richfaces和jsf组件的各种listener和oncomplete属性的执行顺序是什么?

我的托管 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);
    });

}
4

2 回答 2

1

您的 EL 表达式在oncompleteJSF 生成 HTML/JS 代码时进行评估(因此,在初始 HTTP 请求中)。oncomplete正如您所期望的那样,目前在 JS 中执行它并没有被评估。评估 EL 表达式的不是网络浏览器,而是网络服务器。oncomplete顺便说一下,在 之后执行render。使用 HTTP 流量调试器和 JS 调试器(在 Chrome/IE9/Firebug 中按 F12),您可以轻松跟踪它。

有几种解决方法:

  1. 只需在 jQuery 中调用$.get()or并在普通 servlet中完成这项工作,或者更好的是 JAX-RS Web 服务。$.getJSON()

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

    <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}')然后使用$.parseJSON(). 这是没有意义的。像这样删除参数周围的那些单引号jsonDemo(#{kpilist.json}),然后您就不再需要该$.parseJSON()行了。然后数据已经是 JSON 格式了。

于 2012-08-01T14:31:27.833 回答
0

尝试从 更改a4j:ajaxf:ajax

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

于 2012-08-01T14:24:51.273 回答