2015-08-11 16 views
7

Tôi có chế độ xem tạo dữ liệu và phát trực tuyến trong thời gian thực. Tôi không thể tìm ra cách gửi dữ liệu này đến một biến mà tôi có thể sử dụng trong mẫu HTML của mình. Giải pháp hiện tại của tôi chỉ xuất dữ liệu đến một trang trống khi nó đến, nó hoạt động, nhưng tôi muốn đưa nó vào một trang lớn hơn với định dạng. Làm cách nào để cập nhật, định dạng và hiển thị dữ liệu khi dữ liệu được truyền đến trang?Hiển thị dữ liệu được truyền từ chế độ xem Flask khi nó cập nhật

import flask 
import time, math 

app = flask.Flask(__name__) 

@app.route('/') 
def index(): 
    def inner(): 
     # simulate a long process to watch 
     for i in range(500): 
      j = math.sqrt(i) 
      time.sleep(1) 
      # this value should be inserted into an HTML template 
      yield str(i) + '<br/>\n' 
    return flask.Response(inner(), mimetype='text/html') 

app.run(debug=True) 
+0

bạn đang mong đợi một dòng liên tục của giá trị sản lượng được in màn hình? – chishaku

+0

Có. Vòng lặp for ở trên mô phỏng quá trình dài hơn. Về cơ bản tôi muốn có phản hồi giống như in khi đang chạy. – JeffThompson

+0

Cảm ơn, tôi đã xem bài đăng đó. Điều này có vẻ như một cái gì đó có thể mà không có một thư viện khác? – JeffThompson

Trả lời

9

Bạn có thể truyền dữ liệu theo trả lời nhưng không thể cập nhật động mẫu theo cách bạn mô tả. Mẫu được hiển thị một lần ở phía máy chủ, sau đó được gửi tới máy khách. Bạn sẽ cần sử dụng JavaScript để đọc phản hồi được truyền trực tiếp và xuất dữ liệu ở phía máy khách.

Sử dụng XMLHttpRequest để thực hiện yêu cầu tới điểm cuối sẽ truyền dữ liệu. Sau đó đọc định kỳ từ luồng cho đến khi hoàn thành.

Ví dụ này giả định định dạng tin nhắn rất đơn giản: một dòng dữ liệu duy nhất, theo sau là một dòng mới. Tất nhiên bạn có thể phức tạp trong việc phân tích cú pháp theo ý muốn của bạn, miễn là có cách xác định mỗi thư. Ví dụ, bạn có thể trả về một đối tượng JSON và giải mã nó trên máy khách.

from time import sleep 
from flask import Flask, render_template 
from math import sqrt 

app = Flask(__name__) 

@app.route('/') 
def index(): 
    # render the template (below) that will use JavaScript to read the stream 
    return render_template('index.html') 

@app.route('/stream_sqrt') 
def stream(): 
    def generate(): 
     for i in range(500): 
      yield '{}\n'.format(sqrt(i)) 
      sleep(1) 

    return app.response_class(generate(), mimetype='text/plain') 

app.run() 
<p>This is the latest output: <span id="latest"></span></p> 
<p>This is all the output:</p> 
<ul id="output"></ul> 
<script> 
    var latest = document.getElementById('latest'); 
    var output = document.getElementById('output'); 

    var xhr = new XMLHttpRequest(); 
    xhr.open('GET', '{{ url_for('stream') }}'); 
    xhr.send(); 
    var position = 0; 

    function handleNewData() { 
     // the response text include the entire response so far 
     // split the messages, then take the messages that haven't been handled yet 
     // position tracks how many messages have been handled 
     // messages end with a newline, so split will always show one extra empty message at the end 
     var messages = xhr.responseText.split('\n'); 
     messages.slice(position, -1).forEach(function(value) { 
      latest.textContent = value; // update the latest value in place 
      // build and append a new item to a list to log all output 
      var item = document.createElement('li'); 
      item.textContent = value; 
      output.appendChild(item); 
     }); 
     position = messages.length - 1; 
    } 

    var timer; 
    timer = setInterval(function() { 
     // check the response for new data 
     handleNewData(); 
     // stop checking once the response has ended 
     if (xhr.readyState == XMLHttpRequest.DONE) { 
      clearInterval(timer); 
      latest.textContent = 'Done'; 
     } 
    }, 1000); 
</script> 
+1

Một vài câu hỏi: 1. Trong lệnh 'xhr.open()', "luồng" là tên của hàm Python mà nó nghe? 2. Có cách nào để không nhận được toàn bộ tin nhắn trước đó mỗi lần (và loại bỏ sự cần thiết của 'slice()', biến 'position', vv? – JeffThompson

+2

' {{url_for ('stream')}} 'tạo ra url đến điểm cuối 'stream' khi hiển thị mẫu, không có cách nào để lấy dữ liệu mới, bạn cần theo dõi những gì đã được đọc cho đến thời điểm này. – davidism

Các vấn đề liên quan