Mam pewne dane i musi być aktualizowany za każdym razem, gdy nowe dane pobrane z popychacza. Używam VUE.JS dla reaktywności i zapobiec przeładowaniu wszystkich rzeczy z serwera za każdym razem, gdy zdarzenie zostało wystrzelone.

Muszę zaktualizować swoją tablicę dotyczącą tego warunku.

/**
 *
 * 1. prevent each array chunk to store more than 4 items
 *
 * 2. if all chunk is already contains 4 items, create a new chunk,
 * unshift new data and move oldest item to the new chunk.
 *
 * ------------ example ------------
 *
 * *  const beforeUnshift = [
 * *     0 => [7, 6, 5, 4],
 * *     1 => [3, 2, 1, 0]
 * *  ];
 *
 * *  const afterUnshift = [
 * *    0 => [8, 7, 6, 5],
 * *    1 => [4, 3, 2, 1],
 * *    2 => [0]
 * *  ];
 *
 * *  const afterSecondaryUnshift = [
 * *    0 => [9, 8, 7, 6],
 * *    1 => [5, 4, 3, 2],
 * *    2 => [1, 0]
 * *  ];
 *
 * * and so on...
 */

Spójrz na mój kod, każda strona musi wyświetlać maksymalnie 4 dane. Zaktualizowano po wystrzeleniu zdarzenia, ale aktualizuje aż do dołu, aż strona zostanie odświeżona.

<template>
  <div class="table-swipable" style="overflow-x: hidden;">
    <div class="swiper-wrapper">
      <div class="swiper-slide" v-for="flightChunk in chunkedFlights">
        <div class="table-responsive">
          <table class="table">
            <thead>
              <tr>
                <th class="pl-0 pr-1 border-0 text-center fit-content">
                  <div class="bg-white shadow rounded cardy-th">Flight No.</div>
                </th>
                <th class="px-1 border-0 text-center">
                  <div class="bg-white shadow rounded cardy-th">Airlines</div>
                </th>
                <th class="px-1 border-0 text-center" colspan="2">
                  <div class="bg-white shadow rounded cardy-th">Destination</div>
                </th>
                <th class="px-1 border-0 text-center" colspan="2">
                  <div class="bg-white shadow rounded cardy-th">Departure / Arrival</div>
                </th>
                <th class="pl-1 pr-0 border-0 text-center">
                  <div class="bg-white shadow rounded cardy-th">Status</div>
                </th>
              </tr>
            </thead>
            <tbody class="font-weight-bold">
              <template v-for="flight in flightChunk">
                <tr class="bg-white shadow fit-content">
                  <td class="border-0 py-4 pl-4 rounded-left">
                    <i class="fas fa-plane text-primary mr-3"></i>
                    #{{ flight.id }}
                  </td>
                  <td class="border-0 py-4 pl-4">{{ flight.airline.name }}</td>
                  <td class="border-0 py-4 pl-4 text-center">{{ flight.origin.city }}</td>
                  <td class="border-0 py-4 pl-4 text-center">{{ flight.destination.city }}</td>
                  <td class="border-0 py-4 pl-4 text-center">{{ flight.departure | removeSecond }}</td>
                  <td class="border-0 py-4 pl-4 text-center">{{ flight.arrival | removeSecond }}</td>
                  <td
                    class="border-0 py-4 pl-4 text-primary rounded-right text-center"
                  >{{ flight.status ? flight.status : 'Awaiting confirmation' }}</td>
                </tr>
                <tr class="tr-spacer"></tr>
              </template>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import Swiper from "swiper";
import moment from "moment";

export default {
  data() {
    return {
      flights: {}
    };
  },
  computed: {
    chunkedFlights() {
      return _.chunk(this.flights.data, 4);
    }
  },
  created() {
    Echo.channel("flight-created").listen("FlightCreated", ({ flights }) => {
      this.chunkedFlights[0].unshift(flights[0]);
      this.$forceUpdate();
    });
  },
  filters: {
    removeSecond(time) {
      if (!time) return "";
      return moment(time).format("hh:mm");
    }
  },
  updated() {
    var tableSwipable = new Swiper(".table-swipable", {
      centeredSlides: true,
      slidesPerView: 1,
      spaceBetween: 60,
      autoplay: {
        delay: 30000
      }
    });
  },
  mounted() {
    axios.get("/flights/public").then(response => {
      this.flights = response.data;
    });
  }
};
</script>
1
Donny Pratama 28 luty 2019, 00:24

2 odpowiedzi

Najlepsza odpowiedź

Więc jest to przypadek, w którym ma sens, aby oddzielić dane z warstwy widoku. Ułatwia poradzenie sobie z aktualizacjami, jeśli masz Źródło prawdy, którą aktualizujesz, zamiast próbować zaktualizować swoje kawałki.

Więc kiedy otrzymasz aktualizację, rozcznij go do this.flights.data zamiast kawałka, a następnie sprawić, aby VUE przeliczyć kawałki. Dotyczy to oryginału data macierzy jako jedno źródło prawdy, a aktualizujesz kawałki z niego za każdym razem.

0
frodo2975 28 luty 2019, 00:33

Och, widzę, że Frodo2975 złapał, że nie byłeś niezmienny w obliczonej wartości, a nie do danych. Nie zauważyłem tego. Działa to, jak zamierzasz:

new Vue({
  el: '#app',
  data: {
    flights: [
      7, 6, 5, 4, 3, 2, 1, 0
    ]
  },
  computed: {
    chunkedFlights() {
      return _.chunk(this.flights, 4);
    }
  },
  mounted() {
    setTimeout(() => {
      this.flights.unshift(8);
    }, 2000);
  }
});
#app {
  display: grid;
  grid-gap: 2rem;
  background-color: black;
  padding: 0.6rem;
}

.page {
  background-color: #ffe;
  padding: 0.6rem;
  grid-gap: 0.2rem;
  display: grid;
}

.row {
  background-color: blue;
  color: white;
  padding: 0.6rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="chunk in chunkedFlights" class="page">
    <div v-for="flight in chunk" class="row">
      {{flight}}
    </div>
  </div>
</div>
0
Roy J 28 luty 2019, 02:26