programing

렌더링하기 전에 데이터를 기다리는 Vue JS

shortcode 2022. 7. 10. 21:06
반응형

렌더링하기 전에 데이터를 기다리는 Vue JS

몇 주 동안 VueJ에서 데이터를 렌더링하는 데 문제가 있었습니다.

내가 하고 있는 일은 (다른 안에 있는) 공리 호출을 하는 것이다.문제는 콜이 완료되기 전에 데이터가 렌더링되기 때문에 뷰에 아무것도 표시되지 않는다는 것입니다.

"대기"와 "비동기 호출"을 하는 코드를 몇 개 봤지만 문제를 해결하지 못하는 것 같습니다.

또한 렌더링 전에 비동기 데이터를 대기하도록 구성 요소를 가져오지만 작동하지 않습니다.

코드는 다음과 같습니다.

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

        }

    }

데이터가 반환되기 전에 구성 요소가 렌더링되지 않도록 하려면 다음을 수행합니다.

  1. 데이터에 "isFetch" 속성을 추가하고 "true"로 설정합니다.

  2. 가져오기 콜백에서 isFetch를 "false"로 설정합니다.

3. add v-if="!is컴포넌트 래퍼로 가져오기"

당신은 약속을 제대로 처리하지 못해서 계속 해결되지 않고 있어요.사용할 수 있습니다.async,await, 일반 Promise Objects를 사용하는 것이 좋습니다.

getDetails()다른 이야기에요.루프를 만들고 있습니다.forEach루프: Axios 요청을 보냅니다.Axios 호출에서 반환된 Promise를 배열에 저장하여 호출하고 Promise를 호출해야 할 수 있습니다.모든 것.

    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!!
        });
    },

이것이 당신이 원하는 것을 달성하기 위한 최선의 방법이라는 것이 아니라 당신의 코드를 작동시키기 위한 하나의 방법이라는 것입니다.여기서 중요한 것은 약속에 대해 배울 필요가 있다는 것입니다.

솔루션:

여러분 감사합니다!

         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)
        },

언급URL : https://stackoverflow.com/questions/54024406/vue-js-waiting-for-data-before-rendering

반응형