Лучший метод для передачи данных из Java/JSF2 bean-компонента в Javascript/jQuery Components в качестве возвращаемых значений

У меня проблемы с нахождением лучшего способа передачи данных из Java-компонента поддержки / управляемого компонента в компонент jQuery/Javascript, такой как Highcharts, чтобы мое веб-приложение генерировало / отображало данные в динамическом режиме в реальном времени. Я довольно хорошо разбираюсь в Java, но у меня довольно ограниченное знание JavaScript/jQuery, в котором я, очевидно, и падаю. Насколько я прочитал, лучший способ - это Ajaxify скрытого поля в моем веб-приложении и передать объект или строку JSON? к нему, а затем передать это значение в мой компонент JS.

Во-первых, это кажется трудоемким, так как у меня будет вызов Ajax для обновления данных JSON, а затем вызов setInterval для повторного чтения данных в компонент JS? Я надеялся, что смогу передать данные прямо в компонент JS...

В любом случае кто-то может просто укрепить мои знания и рассказать мне хороший испытанный и проверенный метод, если он отличается от описанного выше... Руководства / демонстрационные материалы также будут высоко оценены!!

Я также использую Primeface 2.2.1, если это повлияет на предложенную методологию?

ура

союзник

ОБНОВИТЬ:

Код приведен ниже, но я просто хочу описать то, что я пытаюсь достичь быстро: эффективно я пытаюсь реализовать динамическую диаграмму Highcharts, используя простую функцию count++ из моего компонента поддержки. Очевидно, что в дальнейшем я буду использовать канал в реальном времени для предоставления этих данных, но в данный момент я просто пытаюсь заставить работать Highcharts, основываясь на изменении информации из моего компонента поддержки JSF.

Вот моя простая функция подсчета и преобразование в JSON (я не уверен, действительно ли необходим метод JSON, поскольку передается только 1 значение (int), но я хотел бы сохранить этот метод, так как уверен, что буду использовать больше в других частях веб-приложения):

public class TestBean {

    private int output;

    public TestBean() {
        output = 1;
    }

    public int getOutput() {
        return output;
    }

    public void setOutput(int output) {
        this.output = output;
    }

    public void update() {
        setOutput(getOutput() + 1);
    }

    public void prepareChartDate() {
        // Produce you JSON string (I use Gson here)
        RequestContext reqCtx = RequestContext.getCurrentInstance();
        reqCtx.addCallbackParam("chartData", new Gson().toJson(output));
    }
}

Внешний JS-файл Highcharts, опять же стоит отметить, что я сохранил функцию ряда в нижней части диаграммы, чтобы построить / заполнить график, прежде чем я начну добавлять значения, полученные из JSF Beans:

Highcharts.setOptions({
    global: {
        useUTC: false
    }
});

var chart;
$(document).ready(function() {
    chart = new Highcharts.Chart({
        chart: {
            backgroundColor: "#F8F0DB",
            renderTo: 'containerHigh',
            defaultSeriesType: 'area',
            margin: 10,
            marginLeft:30,
            marginBottom:17,
            zoomType: 'y',
            events: {
                load: updateChartData
            }
        },
        title: {
            text: 'Feed Flow Rate '

        },
        xAxis: {
            type: 'datetime',
            tickPixelInterval: 150
        },
        yAxis: {
            title: {
                text: ''
            },
            plotLines: [{
                value: 0,
                width: 1,
                color: '#808080'
            }]
        },
        tooltip: {
            formatter: function() {
                return '<b>'+ this.series.name +'</b><br/>'+
                Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'<br/>'+ 
                Highcharts.numberFormat(this.y, 2);
            }
        },
        legend: {
            enabled: false
        },
        exporting: {
            enabled: false
        },
        plotOptions: {
            area: {
                fillColor: {
                    linearGradient: [0, 0, 0, 100],
                    stops: [
                    [0, Highcharts.getOptions().colors[0]],
                    [1, 'rgba(2,0,0,0)']
                    ]
                },
                lineWidth: 1,
                marker: {
                    enabled: false,
                    states: {
                        hover: {
                            enabled: true,
                            radius: 5
                        }
                    }
                },
                shadow: false,
                states: {
                    hover: {
                        lineWidth: 1                        
                    }
                }
            }
        },
        series: [{
            name: 'Random data',
            data: (function() {
                // generate an array of random data
                var data = [],
                time = (new Date()).getTime(),
                i;

                for (i = -19; i <= 0; i++) {
                    data.push({
                        x: time + i * 10000,
                        y: 50 * Math.random()
                    });
                }
                return data;
            })()
        }]
    });        
}); 

И встроенная функция JS содержится на моей странице XHTML:

Это работает:

 function updateChartData(xhr, status, args) { 
    var series = this.series[0];
    setInterval(function() {            
        var x = (new Date()).getTime()
        y = 50 * Math.random();
        series.addPoint([x, y], true, true);   

    }, 1000)       
//parse it, process it and load it into the chart
}

но когда я пытаюсь передать значение моего бина:

 function updateChartData(xhr, status, args) { 
    var jsonString = args.chartData
    var series = this.series[0];

    setInterval(function() {            
        var x = (new Date()).getTime()
        y = jsonString 
        series.addPoint([x, y], true, true);   

    }, 1000)       
//parse it, process it and load it into the chart
}

Это не работает...

Также я пробовал и remoteCommand и Poll, чтобы заставить диаграмму работать, ни один из которых я не был успешным с:

 <h:form>                       
                    <p:commandButton value="update" action="#{testBean.update}" update="beanvalue"/> 

                    <h:outputText value="#{testBean.output}" id="beanvalue"/> <br />
                    <h:outputText value="#{testBean.output}" id="chartValue"/> <br />

                    <p:commandButton value="Load" type="button" onclick="fetchChartData();"/>
                    <p:remoteCommand name="fetchChartData"
                                     action="#{testBean.prepareChartDate()}"
                                     oncomplete="updateChartTest(xhr, status, args);"/>            
                </h:form>

Как я уже говорил ранее, Bhesh, ваша помощь очень ценится и будет великолепна!

ура

союзник

1 ответ

Решение

Если вы используете PrimeFaces 2.2.1, тогда довольно легко понять, что вы пытаетесь сделать.

ПФ имеет компонент p:remoteCommand с помощью которого вы можете Ajaxicaly вызывать метод управляемого компонента.

<h:form id="frmIrsChartData">
    <p:remoteCommand name="fetchChartData"
                     action="#{chartManagedBean.prepareChartData()}"
                     oncomplete="updateChartData(xhr, status, args);"/>
</h:form>

И в методе prepareChartData() вы создаете свою строку JSON и используете RequestContext предоставленный PF для отправки его обратно клиенту:

public void prepareChartDate() {
    // Produce you JSON string (I use Gson here)
    RequestContext reqCtx = RequestContext.getCurrentInstance();        
    reqCtx.addCallbackParam("chartData", jsonString);
}

И в функции обратного вызова Javascript updateChartData(xhr, status, args) Вы можете обработать ответ JSON и загрузить в график:

function updateChartData(xhr, status, args) {
    var jsonResponse = args.chartData;
    //parse it, process it and load it into the chart
}

И для периодического обновления графика просто используйте Javascript setInterval или же setTimeout и передать name из remoteCommand которая на самом деле является функцией Javascript.

setInterval("fetchChartData()", 5000);

Вот как я это делаю.

ПФ также имеет еще один компонент p:poll что облегчает реализацию живых графиков.

Обновить:

Ты не правильно понял. На

Что вам нужно сделать, так это подготовить готовый документ, а затем начать опрос.

$(document).ready(function() {
    chart = new Highcharts.Chart({
        //....
    });
    // start your poll here
});

p:poll функция обратного вызова updateChartData(xhr, status, args) должен быть глобальным, так что опрос может вызвать его oncomplete событие.

function updateChartData(xhr, status, args) {
    var jsonResponse = args.chartData;
    //parse it, process it and load it into the chart
    //you will load data into the same chart created in document-ready
}

И когда вы используете опрос, вам не нужно setTimeout или же setInterval,

Обновление 2:

Прежде всего, в updateChartData функция, которую вы должны обновить chart что вы создали:

function updateChartData(xhr, status, args) { 
    var series = chart.series[0]; // <--- no more this instead global variable "chart"
    var newData = args.chartData;
    var x = (new Date()).getTime()
    var y = eval('(' + newData + ')');
    series.addPoint([x, y], true, true);
}

Следующий, updateChartData является функцией обратного вызова, поэтому не вызывайте ее самостоятельно, она вызывается удаленной командой каждый раз, когда запрос завершен.

И дайте удаленной команде отдельную форму:

<h:form>
    <p:remoteCommand name="fetchChartData"
                     action="#{testBean.prepareChartDate()}"
                     oncomplete="updateChartData(xhr, status, args);"/>
</h:form>

Примечание в oncomplete="updateChartTest(xhr, status, args);" в вашем коде функция обратного вызова должна быть updateChartTest вместо updateChartTest,

Инициируйте аяксический опрос после того, как график будет загружен:

events: {
       load: function() {
           setInterval("fetchChartData()", 5000); //update the chart every 5 seconds               
       }
}

Только для тестирования, пытаясь вернуть случайное значение из вашего управляемого бина:

public void prepareChartDate() {
    // Produce you JSON string (I use Gson here)
    RequestContext reqCtx = RequestContext.getCurrentInstance();
    reqCtx.addCallbackParam("chartData", new Random().nextInt(500));
}
Другие вопросы по тегам