代码之家  ›  专栏  ›  技术社区  ›  MagicLAMP

异步更新Zabuto日历

  •  0
  • MagicLAMP  · 技术社区  · 7 年前

    我已经更改了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>
    

    全部的 数据一气呵成

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

    { 'tourdates': array_data_object, 'next_url', url_string }
    

    如果没有更多数据,则将next_url(在响应中)设置为空字符串。getTourDates实际上返回API响应。我试着放一个 while nextUrl 循环注释处的代码,但直到调度函数返回时,zabuto日历才显示。

    另一种方法是让ajax调用同时运行多个,在任何冗余的地方只返回null,但是我宁愿首先查询数据库,看看需要多少页,也不愿意浪费ajax调用来找出需要多少异步点击才能获得所有数据。

    1 回复  |  直到 7 年前
        1
  •  0
  •   MagicLAMP    7 年前

    我一时无法进入下一个循环,所以试着axios.all公司,它允许同时异步调用多个get。这并没有改善加载时间,这可能也是一样的,因为这迫使我去看看我的REST 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;
            }
        }
    }