Vue с компонентом VCalendar: синхронизируйте данные с другим экземпляром Vue - PullRequest
0 голосов
/ 17 декабря 2018

Я программирую страницу, которая отображает список встреч в таблице.Также возможно редактировать и удалять встречи.Теперь я хотел бы предложить альтернативное представление с использованием VCalendar .

Данные получены с сервера при загрузке страницы и сохранены в переменной JS.Экземпляр Vue, содержащий таблицу, и компонент VCalendar совместно используют эти данные.Если я редактирую ячейку таблицы, изменения отражаются в компоненте. Но когда я удаляю дату в табличном представлении, она остается в календаре.

Это соответствующий HTML-код (правка: некоторые атрибуты добавлены в td):

<calendar-component></calendar-component>

<table id='meetings-table'>
    <tr v-for='meeting in meetings' :key='date.id'>
        <td contenteditable @blur='handleInput($event,meeting,"name")>
            @{{ meeting.name }}
        </td>
        <td>
            <input type='checkbox' v-model='selected'
                   :value='meeting.id'>
        </td>
    </tr>
</table>

<div>
    <button v-if='selected.length' @click='deleteMeetings'>
        Delete selected rows
    </button>
</div>

Мой JS (правка: добавлен handleInput метод):

let table = new Vue({
    el:'#meetings-table',
    data: {
        selected:      [],
        meetings:  window.meetings,
    },
    methods: {
        /**
         * Deletes selected meetings.
         */
        deleteMeetings: function () {
            let requests = [];

            // Make a single request and store it
            for (let id of this.selected) {
                requests.push(axios.delete('/termine/' + id)
                    .then(response => {
                        // Remove meetings
                        this.meetings = this.meetings.filter(t => t.id != id);
                        // Remove id from list of selected meetings
                        this.selected = this.selected.filter(elem => elem != id);
                    }));
            }

            const axiosArray = axios.all(requests);
        },
        /**
        * Handles edits in table cells.
        */
        handleInput: function($event, meeting, field) {
            const newValue = $event.target.textContent;

            // Update value in $data
            meeting[field] = newValue;

            // AJAX request follows, but is not necessary for this example to work
        }

    }
});

Соответствующие части компонента:

<template>
  <v-calendar :attributes='attributes'>

    <div
      slot='meeting-row'
      slot-scope='{ customData }'>
      <!-- Popover content omitted -->
    </div>

  </v-calendar>
</template>

<script>

let meetings = window.meetings;

export default {
  data() {
    return {
      incId: meetings.length,
      editId: 0,
      meetings,
    };
  },
  computed: {
    attributes() {
      return [
        // Today attribute
        {
          // ...
        },
        // Meeting attributes
        ...this.meetings.map(meeting => ({
          key: meeting.id,
          dates: new Date('2018,11,31'),// moment(meeting.slot.date, 'DD.MM.YY').format('YYYY, MM, DD'), //meeting.dates,
          customData: meeting,
          order: meeting.id,
          dot: {
            backgroundColor: '#ff8080',
          },
          popover: {
            // Matches slot from above
            slot: 'meeting-row',
          }
        }))
      ];
    }
  }
};
</script>

Вот что происходит:

  • Я загружаю страницу, содержащую только одну встречу.Встреча отображается как в таблице, так и в календаре.Vue devtools показывает его в обоих meetings массивах (как в компоненте, так и в другом экземпляре Vue).Используя консоль, я также вижу ее в window.meetings.
  • . После нажатия кнопки удаления (при запуске метода deleteMeetings в моем JS) собрание исчезает из таблицы, но остается в календаре.в массиве meetings компонента и в window.meetings.

Что нужно изменить, чтобы синхронизировать массивы meetings, даже если удаляет собрание встол?Обратите внимание, что я еще не реализовал никаких методов для компонента календаря.

1 Ответ

0 голосов
/ 17 декабря 2018

Календарь и компоненты таблицы должны иметь одно состояние: выбранные в данный момент собрания.Из того, что я понимаю, сейчас у вас есть это состояние в 2 разных местах: table экземпляр Vue и calendar-component, который является потомком какого-то другого экземпляра Vue.

Может выглядеть как вы 'Вы делитесь состоянием уже (с window.meetings), но это не так: вы инициализируете один и тот же набор собраний только при создании компонентов.И тогда изменения в одном компоненте не отражаются в другом компоненте.

То, что вы можете попытаться сделать, это сохранить собрания в «основном» приложении Vue на своей странице, передать их в качестве опор компонентам таблицы и календаря, а затем вызвать события из компонентов таблицы и календаря, когда собранияМассив изменен.Вы также должны определить обработчики событий в «основном» приложении Vue и прослушивать компоненты.Грубый набросок решения:

<div id="app">
    <table-component
        :meetings="meetings" 
        @meetingUpdated="handleMeetingUpdate" 
        @meetingDeleted="handleMeetingDeletion"
    ></table-component>
    <calendar-component 
        :meetings="meetings" 
        @meetingUpdate="handleMeetingUpdate" 
        @meetingDeleted="handleMeetingDeletion"
    ></calendar-component>
</div>

let app = new Vue({
    el:'#app',
    data: {
        meetings: []
    },
    methods: {
        handleMeetingUpdate(event) {
            //
        },
        handleMeetingDeletion(event) {
            //
        },
    }
    //
});

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

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