使用Nuxt JS更新Vuetify表中数据表上的“重复项”

时间:2020-01-25 13:31:28

标签: javascript vue.js vuex vuetify.js nuxt.js

我有一个带数据表的Vue页面,大约每秒钟通过一个外部服务器通过websocket接收一个json对象,并且我想在数据表<v-data-table>中显示此事件(如果不存在或不更新)当前存在的与此新事件对应的行。

每个json对象具有完全相同的结构,类似。

{"name": "john", "sport": "football", "score": "0-0", "startTime": 1234567, "lastUpdate": 123456}

这里的问题是lastUpdate,在许多情况下,score将是唯一随时间变化的字段,但是我的数据表会将其视为新项目并将其添加到表中。

我正在使用由Set支持的数组来减轻这种情况,但是Set AFAIK比较对象本身而不是字段(或类似Java的逐个字段)。

https://vuetifyjs.com/en/components/data-tables中我看到有一个item-key道具,我不知道该在哪里定义和放置它。我相信,如果我可以将每个项目的ID组成为name+sport+startTime,这将是所有事件的唯一关键金额。

例如,在我的vuetify数据表中,我具有以下数据:

| name |    sport   | score     | startTime   | lastUpdated |
----------------------------------------------|-------------|
| John | football   |   0-0     | 12345678    | 123456      |
| Mark | football   |   0-0     | 112458      | 122111      |

然后我收到以下事件:

{"name": "john", "sport": "football", "score": "1-0", "startTime": 1234567, "lastUpdate": 123999}

它应该使用新数据更新数据表的第一行,但它将使用此事件创建新行。

我的问题是,如果一个数据表项已经存在,如何更新它(忽略“ lastUpdate”和“ score”字段)?

我知道我可以遍历数组并进行一个一个的比较,但是我想避免这种方法,而是采用一种更为vuetify / nuxtjs的本地方法来实现。

我的vtable:

<v-data-table
  :headers="headers"
  :items="sportEvents"
  :sort-by="sortBy">
  <template v-slot:item.action="{ item }">
    <v-icon small class="mr-2" @click="editItem(item)">
      edit
    </v-icon>
    <v-icon small @click="hideItem(item)">
      delete
    </v-icon>
  </template>
</v-data-table>

这是我的脚本代码:

<script>
  import SockJS from "sockjs-client";
  import Stomp from "webstomp-client";
  import axios from 'axios';
  export default {
    name: "websocketdemo",
    data() {
      return {
        sportEvents: [],
        send_message: null,
        connected: false,
        headers: [
          {
            text: 'Home Team',
            align: 'left',
            sortable: false,
            value: 'home',
          },
          {
            text: 'Away Team',
            align: 'left',
            sortable: false,
            value: 'away',
          },
          {
            text: 'League',
            value: 'league',
            align: 'left',
            sortable: false,
          },
          { text: 'Start Time', value: 'startTime' },
          { text: 'Last Update (Seconds)', value: 'bookie.lastUpdated' },
          { text: 'Actions', value: 'action', sortable: false }
        ],
        sortBy: 'true',
        editedIndex: -1
      };
    },
    methods: {
      connect() {
        this.socket = new SockJS("http://example.com/event-feed");
        this.stompClient = Stomp.over(this.socket);
        this.stompClient.connect(
          {},
          frame => {
            this.connected = true;

            this.stompClient.subscribe("/topic/event-feed", tick => {
              let listEvents = JSON.parse(tick.body);
              for(let i = 0; i < listEvents.length; i++) {
                this.sportEvents.push(listEvents[i]);
              }
              // Filter out duplicates :: If lastUpdated value differs it is not considered a duplicated - fix this
              this.sportEvents = Array.from(new Set(this.sportEvents))

            });
          },
          error => {
            console.log("Error callback");
            console.log(error);
            this.connected = false;
          }
        );
      },
      disconnect() {
        if (this.stompClient) {
          this.stompClient.disconnect();
        }
        this.connected = false;
      },
      tickleConnection() {
        this.connected ? this.disconnect() : this.connect();
      },
      hideItem(item) {
        const index = this.sportEvents.indexOf(item)
        this.sportEvents.splice(index, 1);
      },
      editItem(item) {
        var config = {
          headers: { 'Content-Type': 'application/json' }
        };

        axios.put('http://example.com/edit/item', {
          sportEventId: item.sportEventId,
          amount: 10
        }, config)
          .then(function (response) {
            alert('Item edited');
          });
      },
      picker(index) {
        return index % 2 === 0 ? 'red' : 'blue';
      }
    },
    mounted() {
      // this.connect();
    },
    computed: {
      sportEventExists() {
        return this.sportEvents.length > 0;
      }
    }
  };
</script>

0 个答案:

没有答案