Datatable - Dynamic update problems
-
Hi,
I’m trying to present a tab controls follow by a unique data-table under. Data-table columns/data is updated according the selected tab of the tab control.
I made an exemple that simulate what I need and here is what I’ve noticed
- The data-table is sometime missing some columns even if they exists in the columns definition variables.
- The data table is sometimes visible, other times not. When that happens, just move it in the DOM order and it re-appears. In my case, I sometimes place it in the tab control and other times after. It tends to disappear between each change “hot plug”.
Here is a screenshot of the example
How it works
- You click on a tab and then the data-table will get new colums definition plus new data rows.
- On the debug pane of Chrome, I ouput :
- The static columns (those are not changing dynamically)
- The new dynamic columns (those are changing dynamically)
- The final columns array resulting of the merge of (static + dynamic columns)
- The number of rows
- You will notice shortly that sometime the data-table is not rending ALL the columns present in the
dynamicDataTableColumns
variables.
Screenshot of missing columns
The datatable is now suppose to have 7 columns
graph, name1, name2, s, r, z, 8
but only those are visiblegraph, name1, name2, 8
. Where ares, r, z
columns ?Now, the code
<template> <div> <q-tabs ref="tabsReportList" class="shadow-2" inverted two-lines @select="handleTabChange"> <q-tab slot="title" v-for="r in tabList" :key="r.name" :name="r.name" :label="r.name"/> <q-data-table :data="datatableData" :config="configDataTable" :columns="dynamicDataTableColumns"> </q-data-table> </q-tabs> <!-- <q-data-table :data="datatableData" :config="configDataTable" :columns="dynamicDataTableColumns"> </q-data-table> --> <span v-html="simulationInfo"></span> </div> </template> <script> import _ from 'lodash' import { QDataTable, QTabs, QTab } from 'quasar' export default { name: 'index', components: { QDataTable, QTabs, QTab }, data () { return { tabList: [], configDataTable: { /* rowHeight: '1.4rem', */ responsive: true, pagination: { rowsPerPage: 10, options: [5, 10, 15, 30, 50, 100] } }, staticDataTableColumns: [ { label: 'Graph', field: 'graph', /* width: '2rem', */ format () { return `<i class="material-icons" style="font-size: 1.6rem">show_chart</i>` } }, { label: 'Name 1', field: 'name1' /* width: '2rem', */ }, { label: 'Name 2', field: 'name2' /* width: '2rem', */ } ], dynamicDataTableColumns: [], datatableData: [], simulationInfo: '' } }, computed: {}, methods: { handleTabChange (activeTabName) { // Generate dynamic new columns const countDynamicColumns = 1 + Math.floor(Math.random() * 10) const newDynamicColumns = _.times(countDynamicColumns, () => _.random(35).toString(36) ).reduce((acc, cur) => { acc.push({ label: cur, /* width: '1.5rem', */ field: cur }) return acc }, []) // Merge static columns with new dynamic column console.log(`staticDataTableColumns :${JSON.stringify(this.staticDataTableColumns)} \n--> (${this.staticDataTableColumns.length} columns)`) console.log(`newDynamicColumns :${JSON.stringify(newDynamicColumns)} \n--> (${newDynamicColumns.length}) columns`) this.dynamicDataTableColumns = this.staticDataTableColumns.concat(newDynamicColumns) console.log(`dynamicDataTableColumns :${JSON.stringify(this.dynamicDataTableColumns)} \n--> (${this.dynamicDataTableColumns.length}) columns`) // Simulate new data const rowsCount = 5 const that = this var newData = [] for (let i = 0; i < rowsCount; ++i) { let r = {} for (let i = 0; i < that.dynamicDataTableColumns.length; ++i) { r[that.dynamicDataTableColumns[i].field] = Math.floor( Math.random() * 200 ) } newData.push(r) } this.datatableData = newData console.log(`datatableData :${JSON.stringify(this.datatableData)} \n--> (${this.datatableData.length}) rows`) // Update simulation information let simInfo = `Column count :${this.dynamicDataTableColumns.length} (` + _.map(this.dynamicDataTableColumns, 'field').join(',') + ')' simInfo += `<br>Rows count :${this.datatableData.length}` this.simulationInfo = simInfo } }, created () { // Simulate dynamic tabs entries this.tabList = Array.apply(null, Array(5)).reduce((acc, cur, idx) => { acc.push({ name: `Tab-${idx.toString()}` }) return acc }, []) } } </script> <style lang="stylus"> </style>
Maybe I made a mistake or maybe those bugs a real ?
I know Quasar is going to upgrade to 0.15 but do you have an approximative date ? I already tried other frameworks first as (element.io) but it was not responsive first so I abandoned it. Now I was undecided between (Quasar vs Vuetify). I finally choosed Quasar for :
- Compatibility with Cordova
- Responsive first and layout + component works all flawlessly on mobile
- Tons of components
What was missing before I start using it :
- i18n for framework’s components. I already use vue-i18n for the rest.
What is NOW missing after I tried it :
- The data-table is not enough customizable, not enough data manipulation function
- Custom function search getting row by row
- We can’t create a column not associated to a specific field (Ex: a link),
But I’m running out of time and the data-table is critical component for me so If I can’t get it work shortly I will regrettably have to migrate to another framework.
Best regards,
-
Missing q-tab-pane with keep-alive attribute?
<q-tabs> <q-tab default name="tab-1" slot="title" icon="refresh"></q-tab> <q-tab name="tab-2" slot="title" icon="home"></q-tab> <q-tab-pane name="tab-1" keep-alive> <q-data-table ... ></q-data-table> </q-tab-pane> <q-tab-pane name="tab-2" keep-alive> ... </q-tab-pane> </q-tabs>
-
Thank your for your time,
I already tried using a q-tab-pane but same problem here.
I tried keep-alive but same problem.
I will post my question on github too as I will not be able to come here any longer. I’m unable to change my password on this forum and my session cookie will probably end shortly,
-
I am facing the same kind of problem. I need to assign columns and data from dynamically coming from resultset of query. But nothing rendering on screen.
Data for columns and data is coming correctly checked using console.log().Is you able to find any solution for this ?
-
Hi, im looking for the same, with the complexity that I also need dynamic <template></template> for every dynamic column. I tryied this:
<q-data-table :data="table" :config="dataTableConfig" :columns="columns"> <template v-for="column in columns" v-if="column.mode" :slot="'col-' + column.field" scope='cell'> [generated content] </template> </q-data-table>
And I 'm getting this error in console:
TypeError: Cannot read property 'key' of undefined
-
In Vue I’ve found reactive data outside of a computed property sometimes difficult to trigger the watchers in nested components.
I have 3 things to try:
1: instead of using:
this.dynamicDataTableColumns = …
Try using the Vue.set method like:
this.$set(this, ‘dynamicDataTableColumns’, YOUR_NEW_COLUMNS)2: if that doesn’t help try moving the handleTabChange code into a computed property that returns a column array based the activeTabName.
3: use v-if in your template to draw a new table for each tab. You will end up with more components but due to the nature of v-if you won’t lose performance as it will only draw the related tabs table
-
It’s been awhile since I looked at the quasar table code, but you could also try triggering the config watcher on the component even with the same data it might force a new render…
this.$set(this, “configDataTable”, this.configDataTable)