如何在不刷新页面的情况下定期更新数据?

5
我将尝试创建一个用于监控系统活动的Web应用程序,并使用Flask作为我的CMS。更具体地说,我现在卡在了尝试在页面不刷新的情况下定期更新系统信息上。目前,我正在通过以百分比形式检索本地信息来测试Web应用程序。
我创建了一个名为“/refresh”的路由,并以JSON格式添加了本地信息:
@app.route('/refresh')
    def refreshData():
        systemInfo = {'cpuload': si.getCPU(), 'memload': si.getMEM(), 'diskload': si.getDiskSpace()}
        return jsonify(systemInfo)

数据看起来是这样的:
{
  "cpuload": 4.3, 
  "diskload": 0.7, 
  "memload": 27.8
}

目前,我正在使用Flask的变量来显示模板中的信息,但我想在HTML脚本中访问JSON数据并将其设置为HTML元素,并定期更新。我尝试过使用knockout,但也无法使其正常工作。我的模板如下所示:

<ul id='sysInfo'>
    <li>Hostname: {{ sysInfo[0] }}</li>
    <li>CPU Core Count: {{ sysInfo[1] }}</li>
    <script type='text/javascript' src="http://code.jquery.com/jquery.min.js"></script>
    <script type='text/javascript' src="http://knockoutjs.com/downloads/knockout-3.1.0.js">
        function update() {
            $.getJSON('/refresh', function(data) {
                $('#cpu').html(data[cpuload]);
                window.setTimeout(update, 5000);
            });
        }
    </script>
    <li>
        <div id="progress">
            <span id="percent">CPU usage: <div id="cpu"></div>%</span>
            <div style ='height: 20px; background-color: green; width: {{ cpuLoad }}%;'></div>
        </div>
        </li>

我知道HTML中的脚本实际上并没有什么意义,但基本上我只想使用getJSON(或任何最优解),获取数据并将该数据放入我的HTML中。

1个回答

5

更新

看看我做的这个jsfiddle,它演示了这一点。只需将按钮单击替换为您需要轮询数据的任何时间:

完整版,带有注释:http://jsfiddle.net/FgbKd/15/

基本版,仅起作用:http://jsfiddle.net/FgbKd/1/

我已经更新了我的jsfiddle,使其更清晰详细。

结束更新

Knockout实际上非常适合这个问题,但对于第一次使用视图模型并使用新数据刷新它的人来说,可能会有些困惑。

function myViewModel (data) {
    data = data || {}; var self = this;
    self = ko.mapping.fromJS(data);
  return self;
}

那是一个自我定义的视图模型。这就是 knockout mapping 所做的 - 从 json 中创建视图模型。否则,你就必须自己构建。现在你需要根据它创建一个对象,并填充数据。你可以这样做:
var myServerData;
$(document).ready(function(){
    myServerData = new myViewModel(data_json_received);    //
    ko.applyBindings(MyObject);     //myServerDataapplies the bindings found in HTML
});

这里,你刚刚创建了myServerData,它是你的knockout对象映射到你的视图模型。这是有趣的部分,实际上就像你玩具一样。 MyObject.cpuload在此处将有一个值。

现在,如果需要刷新myServerData,因为您进行了另一个AJAX调用,并且需要您的视图模型对象反映新数据,则只需执行以下操作:

ko.mapping.fromJS(new_json_data, {}, myServerData);

比如,也许:

$.ajax({ 
  ....
  success : function(data){
     ko.mapping.fromJS(data, {}, myServerData);   //refreshes it
  }
});

太好了,完成了。您的 MyServerData 中包含了您的新 JSON 数据,在页面上的任何 HTML 瞬间反映出来,例如:

<SPAN data-bind="text: cpuload"></SPAN>
<SPAN data-bind="text: diskload"></SPAN>
<SPAN data-bind="text: memload"></SPAN>

所以,加载knockout和knockout mapping JS文件,使用我向你展示的viewmodel,然后使用mapping.fromJS行在获取新数据时更新您的viewmodel。


1
我决定加入一个JSFiddle,向您展示其易用性: http://jsfiddle.net/FgbKd/1/ - Jason
我还没有全部添加进去,但这看起来很不错!谢谢你!我会告诉你它的运行状况。 - njcolvin
只是让您知道,jquery.json js文件也包含在JSFiddle中(它处理JSFiddle的虚假数据的$.toJSON,但您不需要它,因为您正在获取JSON)。我一直在调整以使其更清晰:http://jsfiddle.net/FgbKd/6/ - Jason
@njcolvin - 因为我无法满足于现状并希望澄清:http://jsfiddle.net/FgbKd/9/ - Jason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接