【问题标题】:Vuejs: loading topojson from store and plot with d3Vuejs:从商店加载 topojson 并使用 d3 绘图
【发布时间】:2017-07-20 09:27:46
【问题描述】:

我遇到的问题类似于这个问题: Vue.js/vuex ajax update components with ajax state

首先,我想将一些静态 topojson 文件加载到商店。这发生在 main.js 中的主 vue 实例的挂载上:

new Vue({
    ...
    mounted () {
        this.$store.dispatch('topojsonStore/loadMunicipalityTopo', 
        'static/topojson_data/gem_2014.topojson')
    }
})

这可以毫无问题地加载到商店中。在我想要可视化这些数据的组件中,我可以很好地从存储中访问这些数据:

computed: {
    getMunicipalityTopo () {
        return this.$store.getters['topojsonStore/getMunicipalityTopo']
    }
}

我把绘图功能放在组件中的一个方法下:

methods: {
    plotMunicipalities () {
        var width = 650,
            height = 770
        var path = d3.geoPath()
        .projection(null) // TODO: fix projections
        var svg = d3.select('#map').append('svg')
        .attr('width', width)
        .attr('height', height)
        // Load topojson from store
        let topoJsonData = this.getMunicipalityTopo
        svg.append('path')
        .attr('class', 'municipalities')
        .datum(topoJsonData)
        .attr('d', path)
      }

如果我将它附加到模板中的点击事件,这会很好,如下所示:

<button @click="plotMunicipalities()">Plot municipalities</button>

然而,我想在页面加载时自动绘制这些东西,而不是在点击事件之后。这就是我遇到异步问题的地方...... 例如,将其放入组件中是行不通的,因为商店中的数据仍未加载:

mounted () {
    this.plotMunicipalities()
}

我应该怎么走? store 中的数据加载时如何触发该函数?稍后我应该提到,将加载不同的图层。用户无法更改某些层,但对于此特定层,用户可以更改它。我应该为这些不同的层使用不同的工作流程吗?

【问题讨论】:

    标签: javascript d3.js vue.js vuex


    【解决方案1】:

    一种方法是通过创建一个空的 vue 实例来设置全局事件总线

    var EventBus = new Vue({});
    

    然后让您的 topojsonStore/loadMunicipalityTopo 操作返回如下承诺:

    actions: {
        topojsonStore/loadMunicipalityTopo: ({commit}) => {
            return new Promise((resolve, reject) => {
                commit(...);
                resolve();
            });
        }
    }
    

    然后分派动作,以便您可以使用成功回调并发出这样的事件:

    new Vue({
        ...
        mounted () {
            this.$store.dispatch('topojsonStore/loadMunicipalityTopo', 
            'static/topojson_data/gem_2014.topojson').then(() => {
                EventBus.$emit('store-json-loaded');
            })
        }
    })
    

    现在在要绘制的组件的 created 钩子中设置一个事件侦听器,如下所示:

    created(){
        EventBus.$on('store-json-loaded', () => {
            this.plotMunicipalities();
        });
    }
    

    【讨论】:

      【解决方案2】:

      虽然 Vamsi 的方法肯定会奏效,但我最终还是在组件中使用了 watcher:

      watch: {
      // Execute draw functions when data in store is done loading
      getMunicipalityTopo: function () {
        this.plotMunicipalities()
      }
      

      工作正常!

      【讨论】:

        猜你喜欢
        • 2016-08-04
        • 2017-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-11
        • 2016-01-17
        相关资源
        最近更新 更多