重定向后烧瓶模板不呈现

时间:2019-09-15 11:55:37

标签: javascript python vue.js flask

我正在使用Vue JS和Flask构建一个非常基本的CARTO应用程序。完整的代码可以在in this github repository中找到。

该应用程序的工作方式如下:

  1. 用户以模式形式选择一个选项,然后单击“可视化”按钮。这将发送一个名为loadMap的Vue方法,该方法将发送带有查询字符串(由query计算的属性)值作为有效载荷的POST请求。

  2. 然后,它将路由重定向到另一个模板(map.html),并采用从SQL API调用生成的变量(features)。

  3. 此变量是一个GeoJSON,它将填充地图的数据源。

问题在于执行重定向后,地图模板无法呈现。这是我的Python代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from flask import Flask, render_template, request, url_for, redirect

app = Flask(__name__, static_folder='static', template_folder='templates')

@app.route('/')
def home():
    """Displays the homepage."""

    return render_template('index.html')

@app.route('/query', methods=['POST'])
def query():

    data = request.get_json()
    query = data['query']

    return redirect(url_for('map', query=query))

@app.route('/map', methods=['GET'])
def map():

    query = request.args['query']
    url = 'https://ramiroaznar.carto.com/api/v2/sql?q={}&format=geojson'.format(query)

    session = requests.Session()
    r = session.get(url)
    features = r.json()

    return render_template('map.html', features=features)

if __name__ == '__main__':
    app.run(debug=True)

看起来POST和GET调用正确完成,但是随后重定向未启动,因此未加载地图:

enter image description here

如何解决此问题?有没有更优雅的方法来实现这一目标(使用API​​调用中的数据加载新网站)?

2 个答案:

答案 0 :(得分:0)

尝试呈现模板而不是重定向。

@app.route('/query', methods=['POST'])
def query():
    data = request.get_json()
    query = data['query']
    return render_template('map.html', query=query)

希望这会有所帮助:P

答案 1 :(得分:0)

问题出在我的js代码中。因此,我修复了将映射逻辑移动到vue实例的问题。为了避免使用两个模板,我还简化了python代码。现在该应用程序可以运行了,但是我应该重构js代码以提高性能(加载时间太长)和可伸缩性(地图逻辑应再次移至vue实例之外)。您可以找到工作示例in this glitch repository

以下代码段是我的Flask python代码...

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from flask import Flask, render_template, request, url_for, redirect

app = Flask(__name__, static_folder='static', template_folder='templates')

@app.route('/')
def home():
    """Displays the homepage."""

    return render_template('index.html')

@app.route('/data', methods=['GET'])
def data():

    query = request.args.get('query')
    url = 'https://ramiroaznar.carto.com/api/v2/sql?q={}&format=geojson'.format(query)

    session = requests.Session()
    r = session.get(url)
    features = r.json()

    return features

if __name__ == '__main__':
    app.run(debug=True)

...这是我的js代码:

Vue.config.ignoredElements = [/as-\w+/];

const vm = new Vue({
    el: "#app",
    data: {
        geometryType: 'cities',
        map: false,
        features: {}
    },
    computed: {
        query: function() {
          let table = ''
          if (this.geometryType == 'cities'){
            table = 'ne_10m_populated_places_simple';
          } else {
            table = 'world_borders';
          }
          return `select * from ${table}`
        }
      },
    methods: {
        loadMap: function() {
          this.map = true;

          this.$http.get('/data', {params:  {query: this.query}} ).then(response => {
            this.features = JSON.parse(response.bodyText);
            console.log(this.features);
          }, response => {
            console.log('an error ocurred')
          })
        }
    },
    watch: {

      features: function() {

        const map = new mapboxgl.Map({
          container: 'map',
          style: carto.basemaps.voyager,
          center: [10.151367,51.172455],
          zoom: 2,
          scrollZoom: false
          });

        const nav = new mapboxgl.NavigationControl({ showCompass: false });
        map.addControl(nav, 'top-left');

        carto.setDefaultAuth({
            username: 'cartovl',
            apiKey: 'default_public'
        });

        console.log(this.features);
        const source = new carto.source.GeoJSON(this.features);
        const viz = new carto.Viz();
        const layer = new carto.Layer('layer', source, viz);
        layer.addTo(map, 'watername_ocean');
    }

  }
})