Vuejs:从商店加载topojson并用d3加载情节

时间:2017-07-20 09:27:47

标签: javascript d3.js vue.js vuex

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

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

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)
      }

如果我将此附加到模板中的click事件,这样可以正常工作:

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

但是,我希望在加载页面时自动绘制这些内容,而不是在单击事件之后。这是我遇到异步问题的地方...... 例如,将它放在组件中不起作用,因为仍未加载商店中的数据:

mounted () {
    this.plotMunicipalities()
}

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

2 个答案:

答案 0 :(得分: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(){
    EventBus.$on('store-json-loaded', () => {
        this.plotMunicipalities();
    });
}

答案 1 :(得分:0)

虽然Vamsi的方法肯定会奏效,但我最终在组件中使用了一个观察者:

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

工作正常!