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

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

问题描述

我无法确定将数据从 Java 支持/托管 bean 传递到 jQuery/Javascript 组件(例如 Highcharts)的最佳方法,以便我的 Web 应用程序以动态、实时的方式生成/显示数据.我在 Java 方面非常扎实,但我对 JavaScript/jQuery 的了解非常有限,这显然是我失败的地方.据我所知,最好的方法是 Ajaxify 我的网络应用程序上的隐藏字段并传递一个 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.

首先,这似乎有点费力,因为我需要通过 Ajax 调用来更新 JSON 数据,然后通过 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?

干杯

盟友

更新:

代码在下面,但我只想描述我想要快速实现的目标:实际上,我正在尝试使用来自支持 bean 的简单 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 个值(整数),但我想保留这个方法,因为我相信我会在网络应用的其他部分更广泛地使用):

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
}

那行不通...

此外,我一直在尝试使用 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!

干杯

盟友

推荐答案

如果您使用的是 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 setIntervalsetTimeout 并传递 remoteCommandname> 这实际上是一个 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) 需要是全局的,以便 poll 可以在 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
}

当您使用 poll 时,您不需要 setTimeoutsetInterval.

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

更新 2:

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

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.

并且,给远程命令一个单独的形式:

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天全站免登陆