Currently, I am working with a Vue Router set up that consists of two components: a list view and a detailed view. The challenge I am facing is when the data is fetched via ajax, the non-router list updates successfully but the router view does not reflect the changes.
I am looking for a solution to communicate with the router view in order to trigger a redraw with the new data. As of now, clicking on an item in the non-router list correctly navigates to the details component, and clicking "show list" navigates back to the list component with the updated data.
If you want to take a closer look at the code, I have prepared a jsFiddle with the relevant snippets here: https://jsfiddle.net/pengman/jkwvphf9/2/ (The ajax call is emulated using setTimeout for demonstration purposes.)
Here is the structure of my HTML:
<div id="app">
Router-view:
<router-view class="view"></router-view>
<br>
Unrouted list:
<div class="list-group">
<router-link v-for="plante in planter" class="list-group-item" :to="{ name: 'plante', params: { nummer: plante.Nummer }}">{{ plante.Navn }} | </router-link>
</div>
</div>
<template id="plante-listing-template">
<ul>
<li v-for="plante in planter">
{{ plante.Navn }} <router-link :to="{ name: 'plante', params: { nummer: plante.Nummer }}">Vis</router-link>
</li>
</ul>
</template>
<template id="plante-detail-template">
<div>
plant detail template:
<h3>{{ plante.Navn }}</h3>
<router-link to="/">Show List</router-link>
</div>
<br>
</template>
And here is the JavaScript code snippet:
var PlanteListing = {
template: '#plante-listing-template',
data: function () {
return {
planter: this.$parent.planter
}
},
watch: {
'$route'(to, from) {
// Need to update data to recalculate
this.planter = this.$parent.planter;
},
'dataloaded'() {
this.planter = this.$parent.planter;
}
}
};
var PlanteDetail = {
template: '#plante-detail-template',
data: function () {
var parent = this.$parent;
var nummerFromRoute = this.$route.params.nummer;
var filtered = this.$parent.planter.filter(function (item) {
return (item.Nummer == nummerFromRoute) ? item : false;
});
return {
season: filtered[0]
}
},
watch: {
'$route'(to, from) {
var nummerFromRoute = this.$route.params.nummer;
var filtered = this.$parent.planter.filter(function (item) {
return (item.Nummer == nummerFromRoute) ? item : false;
});
this.plante = filtered[0];
},
}
};
var router = new VueRouter({
mode: 'hash',
base: window.location.href,
routes: [
{ path: '/', component: PlanteListing },
{ name: 'plante', path: '/:nummer', component: PlanteDetail }
]
});
var app = new Vue({
router,
data: {
planter: []
},
components: { PlanteListing: PlanteListing },
methods: {
getJson: function () {
var self = this;
/* Simulation code: */
setTimeout(function(){
self.planter = [
{ "Nummer": "0", "Navn": "Bertha Winters" },
{ "Nummer": "1", "Navn": "Jeannie Small" },
{ "Nummer": "2", "Navn": "Mckay Joyner" },
{ "Nummer": "3", "Navn": "Janelle Banks" },
{ "Nummer": "4", "Navn": "Bray Moran" },
{ "Nummer": "5", "Navn": "Hooper Schwartz" }
];
console.log('data loaded')
}, 500);
}
},
created: function () {
this.getJson();
}
}).$mount('#app');