Vue JS ждет данных перед рендерингом - PullRequest
0 голосов
/ 03 января 2019

У меня несколько недель проблемы с отображением данных с помощью VueJS.

Что я делаю, так это делаю несколько аксиос звонков (один внутри другого). Моя проблема в том, что данные отображаются перед завершением вызовов, поэтому в представлении ничего не отображается.

Я видел несколько кодов, которые выполняют «ожидание» и «асинхронные вызовы», но, похоже, ничто не решает мою проблему.

Также здесь есть нечто подобное Получить компонент для ожидания асинхронных данных перед рендерингом Но тоже не работает

вот мой код:

<template>
 <div class="m-portlet m-portlet--full-height" m-portlet="true" id="m_portlet_validate_agenda">
...
<div class="m-portlet__body">
    <div class="tab-content">
        <div class="tab-pane active" id="m_widget2_tab1_diagnose">
            <div class="m-widget2">
                <div v-for="diagnose in diagnoses" v-if="diagnoses.length" :class="'m-widget2__item m-widget2__item--' + diagnose.delayColor[0]">
                    <div class="m-widget2__checkbox" >
                        <label class="m-checkbox m-checkbox--solid m-checkbox--single m-checkbox--brand">
                            <span class="m--bg-white" v-html="diagnose.concurrence"></span>
                        </label>
                    </div>
                    <div class="m-widget2__agenda col-2">
                        {{ diagnose.started_at | moment("HH:mm A") }}
                    </div>
                    <div class="m-widget2__desc" v-if="!isFetching">
                        <div>
                            <span class="m-widget2__text">

                            </span><br>
                            <span class="m-widget2__user-name">
                                <a href="#" class="m-widget2__link m-link">
                                Paciente: 
                                {{ diagnose.details[0].name }}
                                </a><br>
                                <a href="#" class="m-widget2__link m-link">
                                Tratante: 

                                </a>
                            </span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
     </div>
   </div>
 </div>
</template>

<script>
export default {

    data() {
        return {
            events: [],
            diagnoses: [],
            urgencies: [],
            treatments: [],
            isFetching: true
        }
    },

    mounted() {
        this.loadData();
    },

    methods: {

        loadData: async function() {
            await axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos').then(res => {
                this.events = res.data;
                this.diagnoses = [];
                this.urgencies = [];
                this.treatments = [];
                this.getDetails();
                this.getDelayColor();
                this.getConcurrence();
                vm.$nextTick(function () {
                    $('[data-toggle="m-tooltip"]').tooltip();
                });
                console.log('end LoadData');
            });
        },

        getDetails: function() {
            console.log('cargando');
            this.events.forEach(event => {
                axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos/' + event.id).then(res => {
                    event.details = res.data;
                    console.log(res.data);
                });
            });
            this.distributeEvents();
            console.log('montado');
        },    

        distributeEvents: function() {
            this.events.forEach(event => {
                if ( event.event.event_type == "diagnosis" )
                {
                    this.diagnoses.push(event);
                }
                else if ( event.event.event_type == "urgency" )
                {
                    this.urgencies.push(event);
                }    
                else if ( event.event.event_type == "treatment" )
                {
                    this.treatments.push(event);
                }
            });
            this.isFetching = false;
        },

        getDelayColor: function() {
            this.events.forEach(event => {
                do something...
            });
        },

        getConcurrence: function() {
            this.events.forEach(event => {                    
                do something...
            });
        },

        diffMinutes: function(started_at) {
            do something...
        }

    }

}

Ответы [ 3 ]

0 голосов
/ 03 января 2019

Решение:

Спасибо вам, ребята!

         loadData: function() {
            axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos')
                .then(res => {
                    this.events = res.data;
                    this.getDelayColor() // sync operation; no need to be returned
                    this.getConcurrence();
                    vm.$nextTick(function () {
                        $('[data-toggle="m-tooltip"]').tooltip();
                    });
                    return this.getDetails(); // Return the promise(s)
                })
                .then((res) => {
                    console.log(res.length);
                    for (var i = 0; i < res.length; i++) {
                        this.events[i].details = res[i].data;
                    }
                    this.distributeEvents();
                    console.log('end LoadData');
                })
                .catch(error => {
                    console.log('error');
                })
        },

        getDetails: function() {
            let url = '/pacientes/request-json/agenda/validarAsistencia/eventos/';
            let promisedEvents = [];

            this.events.forEach(event => {
                promisedEvents.push(axios.get(url + event.id))
            });

            return Promise.all(promisedEvents)
        },
0 голосов
/ 03 января 2019

Вы не обрабатываете обещания должным образом, поэтому они продолжают получать неразрешенные .Вы можете использовать async, await, хотя я предпочитаю использовать простые Обещающие объекты :

getDetails() - это другая история.Вы делаете цикл, и forEach цикл вы отправляете запрос axios .Вам может потребоваться сохранить каждый Promise , возвращаемый каждым axios вызовом, в массиве, чтобы затем вызывать Promise.all .

    getDetails: function() {
        let url = '/pacientes/request-json/agenda/validarAsistencia/eventos/';
        console.log('loading');
        let promisedEvents = [];

        this.events.forEach(event => {
            promisedEvents.push(axios.get(url + event.id))
        });

        return Promise.all(promisedEvents)
    },

После этого я бы сделал что-то вроде этого:

    loadData: function() {
        axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos')
            .then(res => {
                this.events = res.data;
                this.getDelayColor() // sync operation; no need to be returned
                return this.getDetails(); // Return the promise(s)
            })
            .then((res) => {
                // do something with the response from your array of Promises
            })
            .then(anotherPromise) // You can also return a promise like this 
            .catch(handleError) // Very important to handle your error!!
        });
    },

Я не говорю, что это лучший способ достичь того, чего вы можете хотеть, но это один из способов заставить ваш код работать.Важно то, что вам нужно узнать об обещаниях.

0 голосов
/ 03 января 2019

Чтобы предотвратить рендеринг компонента до возвращения данных, вы можете:

  1. добавить свойство «isFetching» к данным и установить его в «true»

  2. в обратном вызове выборки установите для isFetching значение "false"

3.add v-if = "! IsFetching" для оболочки компонента

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...