我有Zabuto日历显示预订日期,但是有些旅行团在该期间有很多日期,并且加载它们很慢。 我已经更改了API以对数据进行分页,如果还有更多数据要加载,则发送下一个url,但是我看不到如何在显示后立即让zabuto日历更新其数据,并且Javascript是最终的异步方法编程语言,我认为日历必须有一种可以同时显示和上传数据的方式。
这样的帖子 How to load data from ajax to zabuto calendar plugin? 展示了如何通过ajax调用来加载日历数据,但是没有显示在显示当前日历数据的同时如何连续不断地异步上传更多数据。其他帖子表明唯一的方法是重新加载整个日历 reloading AJAX data for Zabuto Calendar after modal dismissal。我更喜欢异步方式。
以前的开发人员开始使用Vue框架,所以我拥有的是Zabuto日历Vue模块
<template>
<div id="my-calendar-a"></div>
</template>
<script>
import Vue from 'vue'
import moment from 'moment'
import { mapGetters } from 'vuex'
export default {
name: 'ZabutoCalendar',
methods: {
initialise: function () {
$('.calendar-month-navigation .glyphicon').click(function () {
Vue.bus.$emit('calendar-change-month')
})
}
},
props: ['tour'],
computed: {
...mapGetters('cart', [
'cartItems'
]),
...mapGetters('calendar', [
'tourDates'
])
},
mounted: function () {
var self = this
var currentDate = new Date()
/*
Use of the thrid party plugin zabuto calendar to
set up the calendar and check if dates are being clicked
https://github.com/zabuto/calendar
*/
var nextUrl = '/api/check-dates?year=' + moment().format('YYYY') +
'&month=' + moment().format('M') + '&tour=' + self.tour;
this.$store.dispatch('calendar/getTourDates', nextUrl).then(response => {
// I tried putting a while nextUrl loop here, but the calender wont display till dispatch returns
nextUrl = self.tourDates[1].next_url;
$(self.$el).zabuto_calendar({
data: self.tourDates[0].tourdates,
weekstartson: 0,
show_previous: false,
year: currentDate.getFullYear(),
month: currentDate.getMonth() + 1,
action: function () {
if ($(this).find('> div').hasClass('start_spots')) {
// reconstruct data
var selectedTour = {}
var id = this.id
var elem = $('#' + id)
$('.calendar-dow .selected').removeClass('selected')
$(this).find('> div').addClass('selected')
selectedTour = _.find(self.tourDates[0].tourdates, { 'tour_date_id': elem.data('tour_date_id') })
selectedTour['styled_date'] = moment(elem.data('date')).format('Do MMMM YYYY')
if ($(this).find('> div').hasClass('start_future')) {
selectedTour['available'] = 1
for (var index in self.cartItems) {
if (self.cartItems[index].date === elem.data('date')) {
selectedTour['available'] = 3
break
}
}
} else {
selectedTour['available'] = 2
}
self.$store.commit('calendar/setSelectedTour', selectedTour)
Vue.bus.$emit('date-click')
}
}
})
// while loop could surround above code
})
}
}
</script>
和一个javascript模块进行ajax调用,一次性获取 all 数据
import axios from 'axios'
import moment from 'moment'
export const calendar_module = {
namespaced: true,
state: {
tourDates: [],
selectedTour: {}
},
getters: {
tourDates: (state) => {
return state.tourDates
},
selectedTour: (state) => {
return state.selectedTour
}
},
mutations: {
setSelectedTour (state, selectedTour) {
state.selectedTour = selectedTour
},
setTourDates (state, tourDates) {
state.tourDates = tourDates
}
},
actions: {
getTourDates ({ commit }, datesUrl) {
var response_data = axios.get(datesUrl).then((response) => {
commit('setTourDates', response.data)
});
return response_data;
}
}
}
API响应数据以以下形式返回
{ 'tourdates': array_data_object, 'next_url', url_string }
如果没有更多数据,则将next_url(在响应内)设置为空字符串。 getTourDates实际上返回API响应。我尝试在注释的代码周围放置一个while nextUrl
循环,但是zabuto日历在调度函数返回之前不会显示。
Zabuto Calendar是否具有内置的方式来在显示时异步更新其数据?否则,我如何才能使其异步显示和加载将来的日期?
另一种方法是让ajax调用同时运行几个,并且在任何多余的都返回null,但是我宁愿先查询数据库以查看需要多少页,也不愿浪费一个ajax调用只是为了找出要获取所有数据所需的异步点击次数。
答案 0 :(得分:0)
我无法放入一会儿nextUrl循环,所以尝试了axios.all(),它允许同时异步调用多个获取。这并没有改善加载时间,这也许也是如此,因为它迫使我去看我的REST API,该API效率低下,否则我将无法清理。
这是我的异步解决方案(一旦API变得又好又快,我就不再需要使用该解决方案)
import axios from 'axios'
import moment from 'moment'
export const calendar_module = {
namespaced: true,
state: {
tourDates: [],
selectedTour: {}
},
getters: {
tourDates: (state) => {
return state.tourDates
},
selectedTour: (state) => {
return state.selectedTour
}
},
mutations: {
setSelectedTour (state, selectedTour) {
state.selectedTour = selectedTour
},
setTourDates (state, tourDates) {
if (state.tourDates.length == 0) {
state.tourDates = tourDates[0].tourdates;
} else {
state.tourDates = state.tourDates.concat(tourDates[0].tourdates);
}
}
},
actions: {
getTourDates ({ commit }, datesUrl) {
var response_data = axios.all([
axios.get(datesUrl + '&page=1'),
axios.get(datesUrl + '&page=2'),
axios.get(datesUrl + '&page=3'),
axios.get(datesUrl + '&page=4'),
axios.get(datesUrl + '&page=5'),
axios.get(datesUrl + '&page=6')
]).then(axios.spread(function (response1, response2, response3, response4, response5, response6) {
commit('setTourDates', response1.data);
commit('setTourDates', response2.data);
commit('setTourDates', response3.data);
commit('setTourDates', response4.data);
commit('setTourDates', response5.data);
commit('setTourDates', response6.data)
}));
return response_data;
}
}
}