Выражение JSF El, сохраняющее старое значение (жизненный цикл JSF)

Я создал тестовый проект с JSF2.0 и richfaces. Я пытаюсь построить график. Теперь я получил значение из базы данных в bean и datatable. Теперь, когда я хотел передать это значение в переменную javascript, я нашел этот ответ от The BalusC очень полезным. Он работает нормально, но значение, которое переменная javascript получает после oncomplete="jsonDemo('#{kpilist.json}')". то есть значение # {kpilist.json} не обновлено, оно является последним.

Я напечатал значение #{kpilist.json}. Если он напечатан после базы данных, значение является текущим. Если он напечатан до даты, это последнее значение. В любом случае, так как атрибут oncomplete a4j:ajax выполняется после того, как все завершено, почему # {kpilist.json} не показывает последнее значение? Каков порядок выполнения различных атрибутов listener и oncomplete для richfaces и компонента jsf?

Мой управляемый боб:

@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 ответа

Решение

EL выражение в вашем oncomplete оценивается в тот момент, когда код HTML/JS генерируется JSF (таким образом, по первоначальному HTTP-запросу). Это не оценивается в данный момент oncomplete выполняется в JS, как вы, кажется, ожидаете. Это не веб-браузер, который оценивает выражения EL, это веб-сервер. oncomplete кстати только что казнили после render, С помощью отладчика HTTP-трафика и JS-отладчика (нажмите F12 в Chrome/IE9/Firebug) вы можете легко отследить его.

Есть несколько возможностей решить эту проблему:

  1. Просто вызвать $.get() или же $.getJSON() в jQuery и выполняйте работу в обычном сервлете, а лучше - в веб-сервисе JAX-RS.

    function jsonDemo() {
        $.getJSON("servletURL", function(jsonData) {
            // ...
        });
    }
    
  2. Заменить oncomplete некоторыми <h:outputScript> который вы рендеринг / обновление с помощью ajax.

    <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(), Это не имеет никакого смысла. Удалить эти одинарные кавычки вокруг аргумента, как это jsonDemo(#{kpilist.json}) и тогда тебе это не нужно $.parseJSON() линия больше. Данные тогда уже в формате JSON.

Попробуйте изменить с a4j:ajax в f:ajax

не уверен если a4j:ajax работает с простыми компонентами JSF

Другие вопросы по тегам