将数据从Java / JSF2 bean传递到Javascript / jQuery组件作为返回值的最佳方法 [英] Best method for passing Data from Java/JSF2 bean to Javascript/jQuery Components as return values

查看:132
本文介绍了将数据从Java / JSF2 bean传递到Javascript / jQuery组件作为返回值的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法确定将数据从Java支持/托管bean传递到jQuery / Javascript组件(如Highcharts)的最佳方法,以便我的Web应用程序以动态,实时的方式生成/显示数据。我在Java方面的表现相当不错,但我对JavaScript / jQuery的了解非常有限,这显然是我倒下的地方。到目前为止,我已经阅读过,最好的方法是在我的Web应用程序上Ajax化一个隐藏字段并传递一个JSON对象或字符串?在它中,然后将该值传递给我的JS组件。

I am having trouble nailing down the best method for passing data from a Java backing/managed bean to a jQuery/Javascript component such as Highcharts, so that my web app produces/displays data in a dynamic, real time way. I am pretty solid on my Java side of things but I have a pretty limited knowledge of JavaScript/jQuery which is obviously where I am falling down. So far as I have read, the best way is to Ajaxify a hidden field on my web app and pass a JSON object or string? in to it and then pass that value into my JS component.

首先,这似乎有点费力,因为我会更新JSON数据进行Ajax调用,然后调用setInterval将数据重新读入JS组件?我希望我可以直接将数据传递给JS组件...

Firstly this seems a bit labour intensive as I would have an Ajax call to update the JSON data and then a setInterval call to re-read the data into the JS component? I was hoping that I could pass the data straight into the JS component...

无论哪种方式,有人可以坚定我的知识并告诉我一个经过良好尝试和测试的方法,如果与上述不同...指南/演示也将受到大力赞赏!!

Either way could someone just firm up my knowledge and tell me a good tried and tested method, if different from above... Guides/Demo's would also be massively appreciated!!

如果这会影响建议的方法,我也使用Primeface的2.2.1?

I also use Primeface's 2.2.1 if this will affect a suggested methodology?

干杯

Ally

更新:

代码如下,但我只是想描述一下我想要快速实现的目标:实际上我正在尝试使用我支持的简单count ++函数来实现动态Highcharts图表豆。显然,我将使用实时源提供此数据,但目前我只是想根据我的JSF支持bean更改信息来使Highcharts工作。

Code is below but I just want to describe what I am trying to achieve quickly: Effectively I am trying to implement a dynamic Highcharts chart, using a simple count++ function from my backing bean. Obviously further down the line I will be using a real-time feed to provide this data but at the moment I am just trying to get Highcharts to work based of changing information from my JSF backing bean.

这是我的简单计数函数和转换为JSON(我不确定JSON方法是否真的有必要,因为只传递了1个值(int),但是我我希望保留这种方法,因为我相信我会更广泛地使用网络应用的其他部分):

Here is my simple count function and conversion to JSON (I am not sure if the JSON method is really necessary since only 1 value(int) is being passed, but I would like to retain this method as I am sure I will be using more extensively on other parts of the web app):

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

Highcharts外部JS文件,值得注意的是我在我开始附加从JSF Beans获得的值之前,已经在图表底部维护了系列函数来构建/填充图表:

Highcharts External JS File, again its worth noting that I have maintained the series function at the bottom of the chart to build/populate the graph before I start appending values obtained from the 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;
            })()
        }]
    });        
}); 

在我的XHTML页面上保存了内联JS函数:

And the inline JS Function held on my XHTML page:

这有效:

 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
}

但是当我尝试传递我的bean值时:

but when I try to pass my bean value:

 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
}

这不起作用......

That doesnt work...

我也一直在尝试使用remoteCommand和Poll为了使图表起作用,我都没有成功:

Also I've been trying both remoteCommand and Poll to get the chart to work, neither of which I have been successful with:

 <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之前所说,你的帮助非常受欢迎,现在再好不过了!

As I've said before Bhesh, your help is massively appreciated and anymore would be great!

干杯

Ally

推荐答案

如果您使用 PrimeFaces 2.2.1 ,那么实现您的目标应该非常容易。

If you are using PrimeFaces 2.2.1 then it should be pretty easy to acheive what you are trying to do.

PF有一个组件 p:remoteCommand ,您可以使用Ajaxicaly调用托管bean方法。

PF has a component p:remoteCommand with which you can Ajaxicaly invoke a managed-bean method.

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

在方法 prepareChartData()中你生成您的JSON字符串并使用PF提供的 RequestContext 将其发送回客户端:

And in the method prepareChartData() you produce your JSON string and use RequestContext provided by PF to send it back to client:

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响应并加载到图表中:

And in the Javascript callback function updateChartData(xhr, status, args) you can process the JSON response and load into the chart:

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

并定期更新图表只需使用Javascript setInterval setTimeout 并传递名称 remoteCommand 实际上是一个Javascript函数。

And to periodically update the chart just use the Javascript setInterval or setTimeout and pass the name of the remoteCommand which is actually a Javascript function.

setInterval("fetchChartData()", 5000);

我就是这样做的。

PF还有另一个组件 p:poll ,这样可以更容易地实现实时图表。

PF also has another component p:poll which makes it easier to implement live charts.

更新:

你弄错了。在

您需要做的是先准备好文档,然后开始轮询。

What you need to do is on document-ready render the chart first and then start you poll.

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

p:poll 回调函数 updateChartData(xhr,status,args)需要是全局的,以便民意调查可以在 oncomplete 事件上调用它。

The p:poll callback function updateChartData(xhr, status, args) needs be global so that the poll can call it on oncomplete event.

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

And when you are using poll you do not need the setTimeout or setInterval.

更新2:

首先,在 updateChartData 函数中,您应该更新您创建的图表

First of all, in updateChartData function you are supposed to update the chart that you created:

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 是回调函数所以不要自己调用它,每次请求完成时都会被remote-command调用。

Next, updateChartData is callback function so don't call it yourself, it is called by the remote-command every time the request is complete.

并且,将remote-command分开它的形式:

And, give the remote-command a separate form of it's own:

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

注意 oncomplete =updateChartTest(xhr,status,args); 在你的代码中,回调函数应该是 updateChartTest 而不是 updateChartTest

Note in oncomplete="updateChartTest(xhr, status, args);" in your code the callback function should be updateChartTest instead of updateChartTest.

在图表完成加载后触发ajaxical轮询:

Trigger the ajaxical polling after the chart is done loading:

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

仅供测试,尝试从您的托管bean返回一个随机值:

For testing only, trying returning a random value from you managed-bean:

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

这篇关于将数据从Java / JSF2 bean传递到Javascript / jQuery组件作为返回值的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆