We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Reacting to changes in the bound data

In a Vue.js application I have a Syncfusion Data Grid which is bound to a local array of items. The array itself is static, but the items in the array have their values updated by the application.

The data array and the items it contains are reactive (If I bind a simple HTML table to the data the cells are re-rendered when the data changes)

However th Syncfusion grid does not react to the data changes. Is there a way to make the grid react when bound row data changes? To be clear the dataSource does not change, but the contents do.


Thanks


11 Replies

TS Thavasianand Sankaranarayanan Syncfusion Team August 2, 2019 12:29 PM UTC

Hi Rob, 

Greetings from Syncfusion support. 

We can achieve your requirement using state property in Vue. 

In the below code example we have changed some values in dataSource and updated through the state property. 

[App.vue] 

<template> 
    <div id="app"> 
        <ejs-button iconCss="e-icons e-play-icon" v-on: click.native="btnClick">Data Update</ejs-button> 
    <ejs-grid : dataSource="this.state.gridOrderData"> 
      <e-columns> 
        <e-column field="OrderID" headerText="Order ID" width="120" textAlign="Right"></e-column> 
        <e-column 
            field="OrderDate" 
            headerText="Order Date" 
            width="130" 
            format="yMd" 
            textAlign="Right" 
        ></e-column> 
        <e-column field="Freight" headerText="Freight" width="120" format="C2" textAlign="Right"></e-column> 
        <e-column 
            field="ShippedDate" 
            headerText="Shipped Date" 
            width="130" 
            format="yMd" 
            textAlign="Right" 
        ></e-column> 
        <e-column field="ShipCountry" headerText="Ship Country" width="150"></e-column> 
    </e-columns> 
    </ejs-grid> 
  </div > 
</template > 
 
    <script> 
        import Vue from "vue"; 
import {GridPlugin, Page } from "@syncfusion/ej2-vue-grids"; 
import {ButtonPlugin} from "@syncfusion/ej2-vue-buttons"; 
import {data} from "./datasource"; 
         
        Vue.use(GridPlugin); 
        Vue.use(ButtonPlugin); 
         
export default { 
            data() { 
        return { 
            state: { 
            gridOrderData: data 
      } 
    }; 
  }, 
  provide: { 
            grid: [Page] 
      }, 
  methods: { 
            btnClick(args) { 
 
      this.state.gridOrderData = [{ 
            OrderID: 12121, 
        CustomerID: "VINET", 
        OrderDate: "1996-07-04T00:00:00.000Z", 
        ShippedDate: "1996-07-16T00:00:00.000Z", 
        Freight: 32.38, 
        ShipName: "Vins et alcools Chevalier", 
        ShipAddress: "59 rue de l'Abbaye", 
        ShipCity: "Reims", 
        ShipRegion: null, 
        ShipCountry: "France" 
      }, 
  { 
            OrderID: 233434, 
        CustomerID: "dfdfdf", 
        OrderDate: "1996-07-05T00:00:00.000Z", 
        ShippedDate: "1996-07-10T00:00:00.000Z", 
        Freight: 11.61, 
        ShipName: "Toms Spezialitäten", 
        ShipAddress: "Luisenstr. 48", 
        ShipCity: "Münster", 
        ShipRegion: null, 
        ShipCountry: "Germany" 
      }, 
  { 
            OrderID: 3434545, 
        CustomerID: "dfdfdf", 
        OrderDate: "1996-07-08T00:00:00.000Z", 
        ShippedDate: "1996-07-12T00:00:00.000Z", 
        Freight: 65.83, 
        ShipName: "Hanari Carnes", 
        ShipAddress: "Rua do Paço, 67", 
        ShipCity: "Rio de Janeiro", 
        ShipRegion: "RJ", 
        ShipCountry: "Brazil" 
      }, 
  { 
            OrderID: 454534, 
        CustomerID: "dfdfdf", 
        OrderDate: "1996-07-08T00:00:00.000Z", 
        ShippedDate: "1996-07-15T00:00:00.000Z", 
        Freight: 41.34, 
        ShipName: "Victuailles en stock", 
        ShipAddress: "2, rue du Commerce", 
        ShipCity: "Lyon", 
        ShipRegion: null, 
        ShipCountry: "France" 
      }, 
  { 
            OrderID: 10252, 
        CustomerID: "SUPRD", 
        OrderDate: "1996-07-09T00:00:00.000Z", 
        ShippedDate: "1996-07-11T00:00:00.000Z", 
        Freight: 51.3, 
        ShipName: "Suprêmes délices", 
        ShipAddress: "Boulevard Tirou, 255", 
        ShipCity: "Charleroi", 
        ShipRegion: null, 
        ShipCountry: "Belgium" 
      }, 
  { 
            OrderID: 10253, 
        CustomerID: "HANAR", 
        OrderDate: "1996-07-10T00:00:00.000Z", 
        ShippedDate: "1996-07-16T00:00:00.000Z", 
        Freight: 58.17, 
        ShipName: "Hanari Carnes", 
        ShipAddress: "Rua do Paço, 67", 
        ShipCity: "Rio de Janeiro", 
        ShipRegion: "RJ", 
        ShipCountry: "Brazil" 
      }, 
  { 
            OrderID: 10254, 
        CustomerID: "CHOPS", 
        OrderDate: "1996-07-11T00:00:00.000Z", 
        ShippedDate: "1996-07-23T00:00:00.000Z", 
        Freight: 22.98, 
        ShipName: "Chop-suey Chinese", 
        ShipAddress: "Hauptstr. 31", 
        ShipCity: "Bern", 
        ShipRegion: null, 
        ShipCountry: "Switzerland" 
      }, 
  { 
            OrderID: 10255, 
        CustomerID: "RICSU", 
        OrderDate: "1996-07-12T00:00:00.000Z", 
        ShippedDate: "1996-07-15T00:00:00.000Z", 
        Freight: 148.33, 
        ShipName: "Richter Supermarkt", 
        ShipAddress: "Starenweg 5", 
        ShipCity: "Genève", 
        ShipRegion: null, 
        ShipCountry: "Switzerland" 
      }, 
  { 
            OrderID: 10256, 
        CustomerID: "WELLI", 
        OrderDate: "1996-07-15T00:00:00.000Z", 
        ShippedDate: "1996-07-17T00:00:00.000Z", 
        Freight: 13.97, 
        ShipName: "Wellington Importadora", 
        ShipAddress: "Rua do Mercado, 12", 
        ShipCity: "Resende", 
        ShipRegion: "SP", 
        ShipCountry: "Brazil" 
      }, 
  { 
            OrderID: 10257, 
        CustomerID: "HILAA", 
        OrderDate: "1996-07-16T00:00:00.000Z", 
        ShippedDate: "1996-07-22T00:00:00.000Z", 
        Freight: 81.91, 
        ShipName: "HILARION-Abastos", 
        ShipAddress: "Carrera 22 con Ave. Carlos Soublette #8-35", 
        ShipCity: "San Cristóbal", 
        ShipRegion: "Táchira", 
        ShipCountry: "Venezuela" 
      }, 
  { 
            OrderID: 10258, 
        CustomerID: "ERNSH", 
        OrderDate: "1996-07-17T00:00:00.000Z", 
        ShippedDate: "1996-07-23T00:00:00.000Z", 
        Freight: 140.51, 
        ShipName: "Ernst Handel", 
        ShipAddress: "Kirchgasse 6", 
        ShipCity: "Graz", 
        ShipRegion: null, 
        ShipCountry: "Austria" 
      }]; 
        } 
      } 
    }; 
</script> 


We have prepared  a simple sample in the following link. 


Regards, 
Thavasianand S. 



RL Rob Lugt August 2, 2019 02:28 PM UTC

Hi Thavasianand

The example you have shown below updates the array that DataSource is bound to, which causes the grid to completely redraw.

What I am after is a change to a single element of the array, and that change to be reflected in the grid.

vue.js makes the array and all the members of the array reactive, so I would like to know if the Syncfusion data grid can react to that individual change?

I have updated your example to demonstrate exactly what I mean.  Below you grid I have rendered a simple list that is reactive in the way that I desire the grid to be.
https://codesandbox.io/embed/vue-template-ispcg

Many thanks
Rob




TS Thavasianand Sankaranarayanan Syncfusion Team August 5, 2019 12:19 PM UTC

Hi Rob, 
 
As per the Vue standard, we do not have pure two-way binding support for our EJ2 Vue components, but we have model-binding support for form components alone.   
   
 
Note: Vue-cli team deprecated the pure two-way binding support because of some technical snag in their end.    
 
Regards, 
Thavasianand S. 



RL Rob Lugt August 5, 2019 12:25 PM UTC

Hi


I am not looking for 2-way binding.  I want the grid to show changes to the [one-way] bound data.


TS Thavasianand Sankaranarayanan Syncfusion Team August 7, 2019 10:24 AM UTC

Hi Rob, 

Based on your query we suspect that you want to detect the onPush changes in the dataSource. We can achieve your requirement using the below code example. 

[App.Vue] 

 
methods: { 
    btnClick(args) { 
 
        this.state.gridOrderData[0].ShipCountry = 'UK'; 
        this.state.gridOrderData = [...this.state.gridOrderData]; 
 
    } 
} 



We have modified the sample in the following link. 


Regards, 
Thavasianand S. 



RL Rob Lugt August 7, 2019 11:39 AM UTC

Hi Thavasianand

I'm afraid that is not a solution.

The controls that update the local data source do not know (and should not know) about the grid data binding.  Also I suspect this will cause the entire grid to be re-rendered, which goes against the goals of reactive properties.

Regards
Rob


TS Thavasianand Sankaranarayanan Syncfusion Team August 8, 2019 06:19 AM UTC

Hi Rob, 
 
Vue-cli team deprecated the pure two-way binding support because of some technical snag in their end. Grid also has many cells in it so it is not possible to verify onPush detection approach and it also contributes to performance-related issues and we need to update the complete dataSource of Grid is the right way. But we only proposed a workaround in the past update based on your necessity. 
 
 Regards, 
Thavasianand S. 



RL Rob Lugt August 8, 2019 07:03 AM UTC

Hi Thavasianand

What I am after is not two-way binding.  Two-way binding would be where an update made within the grid causes a corresponding update to the data source.  One-way binding, which is the normal mode of operation for vue.js, allows an update in the data source to be rendered in the output.  IT is this type of operation that we need.

I understand that this can have performance implications for a large data source with many cells, so I was anticipating some means of controlling which cells will automatically re-render when changes are made.  I was not anticipating having to re-bind the entire grid each time the value for a single cell changes.

Regards
Rob


TS Thavasianand Sankaranarayanan Syncfusion Team August 9, 2019 09:53 AM UTC

Hi Rob 

Based on your details we found that you want to update a cell in Grid when we changed a single field value in dataSource but we suspect that it relates to two way binding concept. Vue-cli deprecated the two-way binding support because of some technical snag in their end. But in Grid, we have a method called setCellValue and setRowDate in grid by using this method we can change the cell values but in UI level alone it is changed. 

Refer the help documentation. 



Please let us know if you need further assistance on this.  

Regards, 
Thavasianand S. 



NP Naomi Perry April 27, 2021 10:47 PM UTC

Hello, I have the same need as described in this thread (I am sourcing my grid data from my state and expect the grid rows/cells to update when the state data updates). Any chance there's a better/more clean solution now? Having to hardcode logic to specifically cause the grid to react to data updates when I already updated the data seems a little clunky and not ideal. If there isn't a new/better way to handle this, can you provide an example of how to use setRowData for this use case? The link you provided for that doesn't have an example. 


I also followed your pattern above to just set the grid's state.gridData, and that doesn't seem to update the grid in my case.


Here is my code stripped down to show the parts relevant to this issue:

<ejs-grid
ref="grid"
id="Grid"
:allowReordering="true"
:allowPdfExport="true"
:toolbarClick="toolbarClick"
:toolbar="toolbarOptions"
:dataSource="this.state.gridData"
:load="load"
:allowPaging="true"
:allowSorting="true"
:pageSettings="pageSettings"
:allowExcelExport='true'
:allowGrouping='true'
:rowDataBound='rowDataBound'
:commandClick="commandClick"
:height="'auto'"
>
<e-columns>
<e-column v-for="column in columns"
:key="column.id"
:customAttributes="column.customAttributes"
:disableHtmlEncode="column.disableHtmlEncode"
:template="column.columnTemplate"
:field="column.field"
:headerText="column.headerText"
:width="column.width"
:commands="column.commands"
:textAlign="column.textAlign">e-column>
e-columns>
ejs-grid>



<script>
import { EventBus } from '@/utils/eventBus';
import Vue from 'vue';
import {
GridPlugin,
Sort,
Page,
Toolbar,
Search,
PdfExport,
Reorder,
Group,
ExcelExport,
CommandColumn
} from '@syncfusion/ej2-vue-grids';

Vue.use(GridPlugin);

export default {
props: {
columns: {
type: Array,
required: true
},
pageSize: {
type: Number,
required: true
},
tableData: { // this is the initial data array passed into my wrapper component, I set the state.gridData to this value on mount and it works
type: Array,
required: true
}
},
  data() {
return {
customAttributes: { class: 'customcss' },
toolbarOptions: ['Search', 'PdfExport', 'ExcelExport'],
state: {
gridData: []
}
};
},
mounted() {
this.state.gridData = this.tableData; // this works and the grid loads with the data from props on mount
EventBus.$on('integration_updated', (data) => {
this.updateGrid(data);
});
}
methods: {
    updateGrid: function(dataRow) {
let gridData = this.state.gridData;
const rowIndex = this.state.gridData.findIndex(d => d.id === dataRow.id);
if (rowIndex !== -1) {
gridData[rowIndex] = dataRow;
} else {
gridData.push(dataRow);
}
this.state.gridData = gridData;
console.log(this.state.gridData); // this shows the expected values, but the update is not reflected in the grid, grid doesn't change at all
}
}


BS Balaji Sekar Syncfusion Team April 29, 2021 04:27 PM UTC

Hi Naomi, 
 
Based on your query we have created a sample with setRowData method. In below sample, we have update a CustomerID column value while click on a record using recordClick event. You can use the setRowData method according your requirement. 
 
Please refer the below code example and sample for more information. 
 
[App.Vue] 
recordClick: function (args) { 
      console.log(args); 
      args.rowData.CustomerID = "changed"; 
      setTimeout((e) => { 
        this.$refs.grid.ej2Instances.setRowData( 
          args.rowData["OrderID"], 
          args.rowData 
        ); 
      }); 
    }, 
 
 
Please get back to us, if you need further assistance. 
 
Regards, 
Balaji Sekar 


Loader.
Live Chat Icon For mobile
Up arrow icon