javascriptvue.jsag-grid

Refreshing a cell with a custom CellRenderer in AgGrid causes it to flash


I've got the following AgGrid which has a button to multiply the price column value and a custom cell renderer in the first column.

<template>
  <button @click="convertPrice()">Convert</button>
  <AgGridVue
    :rowData="rowData"
    :columnDefs="colDefs"
    :gridOptions="defaultOptions"
    style="height: 500px"
    class="ag-theme-quartz"
    ref="grid"
  />
</template>

<script setup>
import { ref } from "vue";
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-quartz.css";
import { AgGridVue } from "ag-grid-vue3";
import CustomRenderer from "./components/CustomRenderer.vue";

const grid = ref(null);
const rowData = ref([
  { make: "Tesla", model: "Model Y", price: 64950, electric: true },
  { make: "Ford", model: "F-Series", price: 33850, electric: false },
  { make: "Toyota", model: "Corolla", price: 29600, electric: false },
]);
const colDefs = ref([
  {
    colId: "make",
    cellRenderer: CustomRenderer,
    valueGetter: (params) => ({
      electric: params.data.electric,
      model: params.data.model,
    }),
  },
  { field: "model" },
  { field: "price" },
  { field: "electric" },
]);

let defaultOptions = {
  domLayout: "autoHeight",
  cellFlashDuration: 250,
  cellFadeDuration: 800,
  defaultColDef: {
    enableCellChangeFlash: true,
  },
};

function convertPrice() {
  const gridApi = grid.value.api;

  gridApi.forEachNode((row) => {
    row.data.price = row.data.price * 1.5;
    row.updateData(row.data);
  });
}
</script>

Working example

If you press the Convert button above the grid both price and make columns will flash as if both contents were updated, but only the price values are changing. Why is AgGrid flashing the first column if it doesn't have any updates?

How can I prevent this from happening, so that the only cells that flash are in fact the ones that get updated?


Solution

  • You can create a computed where you calculate the make and use this variable as rowData, that way you can just reference make in your colDefs.

    Create the computed:

    const convertedData = computed(() => 
       rowData.value.map(row => ({
         ...row,
         make: row.electric + row.model
      }))
    );
    

    Update colDefs:

    const colDefs = ref([
      { field: "make" },
      { field: "model" },
      { field: "price" },
      { field: "electric" },
    ]);
    

    Update html:

    <AgGridVue
       :rowData="convertedData"
       :columnDefs="colDefs"
       :gridOptions="defaultOptions"
       style="height: 500px"
       class="ag-theme-quartz"
       ref="grid"
    />