Асинхронное обновление календаря Zabuto - PullRequest
0 голосов
/ 25 августа 2018

У меня есть календарь Zabuto, показывающий даты бронирования, но у некоторых туров есть много дат для периода, и загрузка их происходит медленно. Я изменил API, чтобы разбить данные на страницы и отправить следующий URL, если есть еще данные для загрузки, но я не вижу, как заставить календарь zabuto обновлять свои данные после его отображения, а Javascript является окончательным асинхронным язык программирования, я полагал, что в календаре должен быть способ отображать и загружать данные одновременно.

сообщения, подобные этому Как загрузить данные из ajax в плагин Zabuto Calendar? показывает, как загрузить данные календаря с помощью ajax-вызова, но не как непрерывно загружать дополнительные данные асинхронно, пока отображаются текущие данные календаря. Другие сообщения показывают, что единственный способ - перезагрузить весь календарь. перезагрузка данных AJAX для календаря Zabuto после модального увольнения . Я бы предпочел асинхронный способ.

Предыдущий разработчик начал использовать каркас Vue, поэтому у меня есть модуль Vue календаря Zabuto

<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 для получения всех данных за один раз

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-вызов, чтобы выяснить, сколько асинхронных обращений необходимо для получения всех данных.

1 Ответ

0 голосов
/ 04 сентября 2018

Я не мог вставить цикл while nextUrl, поэтому вместо этого попробовал axios.all (), который допускает асинхронный вызов нескольких запросов одновременно.Это не улучшило время загрузки, что, вероятно, было так же хорошо, потому что заставило меня взглянуть на мой 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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...