Лучший метод для передачи данных из 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));
}