4

I found some similar questions like this and this. But my problem is somewhat different. I'm polling data for table every second from my REST Api with axios. I need is the user to freely manipulate (i.e. order, sort and select) the rows when data updates. In general, when there is data update, all selections are removed and orders are lost.

I've created a local store with my data which I pass as a reference to my table and update it like this:

setStrategies(newStrategies) {
        if (this.state.strategies.length == 0) {
            newStrategies.forEach(strategy => {
                this.state.strategies.push(strategy)
            });
        } else {
            this.state.strategies.forEach(strategy => {
                var newStrategy = newStrategies.find(x => x.strategyName === strategy.strategyName);
                strategy.status = newStrategy.status;
                strategy.lastPingTime = newStrategy.lastPingTime;
            });
        }

It works but I think it's overcomplicated. So could you tell me what is the best approach or may be table-component that could do binding automaticaly?

xneg
  • 1,204
  • 15
  • 24

3 Answers3

1

You can use keys in Vue to items in list. This will handle the refresh of your list and reuse and reorder existing elements.

<div v-for="item in items" :key="item.id">
  <!-- content -->
</div>

As stated in the docs :

When Vue is updating a list of elements rendered with v-for, by default it uses an “in-place patch” strategy. If the order of the data items has changed, instead of moving the DOM elements to match the order of the items, Vue will patch each element in-place and make sure it reflects what should be rendered at that particular index.

This default mode is efficient, but only suitable when your list render output does not rely on child component state or temporary DOM state (e.g. form input values).

To give Vue a hint so that it can track each node’s identity, and thus reuse and reorder existing elements, you need to provide a unique key attribute for each item. An ideal value for key would be the unique id of each item.

tony19
  • 125,647
  • 18
  • 229
  • 307
hlobit
  • 166
  • 6
  • Your solution works for described case. So I'll mark it as an answer. Unfortunately, I'm using Vue material table and it has more complicated implementaion using scopes. I tried to apply your answer and there but it didn't work. – xneg Jun 14 '18 at 08:44
0

I don't understand the code you posted, but I would treat the source array and the filter and sort columns as page state, in your local store. Then, create yourself a computed property on your vue component that orders and sorts the source array. Every time the source array is replaced, the computed property will update. You may also want to look at vue-keep-scroll, so the user's position on the page is preserved across updates.

bbsimonbb
  • 27,056
  • 15
  • 80
  • 110
  • The style of my code is C # legacy. What I do is updating array of strategies (my data) using `strategyName` as binding. Using computed property is good idea but I still nead "manualy" update my source. May be there is another way to use binding in table so that table do all things instead of me? – xneg Jun 13 '18 at 10:06
  • Your second linked answer is a table component on which you can call refresh(). You might find a component that does this. Meteor.js makes a big deal out of "live" DB queries, where all connected clients are automatically updated every time their queries produced a different result set. It is amazing to use, but there's an inevitable price to be paid for such a high level of abstraction. (performance, whole new paradigm, no integration with relational dbs). It has very devoted users, but its curve has flattened. I think you should just get on with it and call your server :-) – bbsimonbb Jun 13 '18 at 13:00
0

I am not diminishing the value other answers but I found that Vuetify table does exact what I want.

xneg
  • 1,204
  • 15
  • 24