Framework:Javascript Data GridAngular Data GridReact Data GridVue Data Grid

Vue Data Grid: Client-Side Data - Transaction Updates

Transaction Updates allow large numbers of rows in the grid to be added, removed or updated in an efficient manner.

Transaction Updates are excellent for applying large data changes with the following advantages:

  • Efficient operation.
  • Updates sort, filter, group, aggregation and pivot after changes applied.

Transaction Update API

A transaction object contains the details of what rows should be added, removed and updated. The grid API applyTransaction(transaction) takes this transaction object and applies it to the grid's data.

The result of the applyTransaction(transaction) is also a transaction, however it is a list of Row Nodes that were added, removed or updated. Both types of transactions look similar, but the difference is the data type they contain.

  • Row Data Transaction: Contains Row Data, the data that you are providing to the grid.
  • Row Node Transaction: Contains Row Nodes, the grid-created objects that wrap row data items.

For each data item in a Row Data Transaction there will typically be a Row Node in Row Node Transaction wrapping that data item. The only exception is for edge cases, for example you tried to delete or update a data item that didn't exist.

// Grid API method for accepting a transaction
function applyTransaction(rowDataTransaction: RowDataTransaction): RowNodeTransaction;

// params for above
interface RowDataTransaction {

    // rows to add
    add?: any[];
    // index to add rows
    addIndex?: number;

    // rows to remove
    remove?: any[];

    // rows to update
    update?: any[];
}

// result for above
interface RowNodeTransaction {

    // Row Nodes added
    add: RowNode[];

    // Row Nodes removed
    remove: RowNode[];

    // Row Nodes updated
    update: RowNode[];
}

Example: Updating with Transaction

The example applies transactions in different ways and prints the results of the call to the console. The following can be noted:

  • Add Items: Adds three items.
  • Add Items addIndex=2: Adds items at index 2.
  • Update Top 2: Updates the price on the first 2 rows in the list.
  • Remove Selected: Removes all the selected rows from the list.
  • Get Row Data: Prints all row data in the grid to the console.
  • Clear Data: Sets the data in the grid to an empty list.

Identifying Rows for Update and Remove

When passing in data to be updated or removed, the grid will be asking:

"What row do you mean exactly by this data item you are passing?"

There are two approaches you can take: 1) Providing Row Node IDs, or 2) Using Object References.

    Providing Row Node IDs (Faster)

    If you are using the grid callback getRowNode (explained in Row Node IDs) then the grid will match data provided in the transaction with data in the grid using the ID.

    For updating rows, the grid will find the row with the same ID and then swap the data out for the newly provided data.

    For removing rows, the grid will find the row with the same ID and remove it. For this reason, the provided records within the remove array only need to have an ID present.

    <ag-grid-vue
        [getRowNodeId]="getRowNodeId"
        /* other grid options ... */>
    </ag-grid-vue>
    
    this.getRowNodeId = (data) => data.employeeId;
    const myTransaction = {
      add: [
          // adding a row, there should be no row with ID = 4 already
          {employeeId: '4', name: 'Billy', age: 55}
      ],
      
      update: [
          // updating a row, the grid will look for the row with ID = 2 to update
          {employeeId: '2', name: 'Bob', age: 23}
      ],
      
      remove: [
          // deleting a row, only the ID is needed, other attributes (name, age) don't serve any purpose
          {employeeId: '4'}
      ]
    }
  • Using Object References (Slower)

    If you do not provide IDs for the rows, the grid will compare rows using object references. In other words when you provide a transaction with update or remove items, the grid will find those rows using the === operator on the data that you previously provided.

    When using object references, note the following:

    1. The same instance of the row data items should be used. Using another instance of the same object will stop the grid from making the comparison.
    2. Using object references for identification will be slow for large data sets, as the grid has no way of indexing rows based on object reference.

Although using object references is slower, this will only be an issue if working with large datasets (over 10,000).

Example: Updating with Transaction and Groups

When using transactions and grouping, the groups are kept intact as you add, remove and update rows. The example below demonstrates the following:

  • Add For Sale: Adds a new item to 'For Sale' group.
  • Add In Workshop: Adds a new item to 'In Workshop' group.
  • Remove Selected: Removes all selected items.
  • Move to For Sale: Move selected items to 'For Sale' group.
  • Move to In Workshop: Move selected items to 'In Workshop' group.
  • Move to Sold: Move selected items to 'Sold' group.
  • When moving items, the grid animates the rows to the new location with minimal DOM updates.
  • Get Row Data: Prints all row data to the console.

Suppressing Top Level Aggregations

When aggregations are present, the grid also aggregates all the top level rows into one parent row. This total aggregation is not shown in the grid so a speed increase can be produced by turning this top level aggregation off by setting suppressAggAtRootLevel=true. It is the intention that a future release of the grid will allow exposing the top level aggregation hence why this feature is left in.

The example in the next section has this property enabled to provide a performance boost.

Localised Changes in Grouped Data

When you apply a transaction to grouped data, the grid will only re-apply grouping, filtering and sorting to the impacted data.

For example, suppose you have the grid with its rows grouped into 10 groups and a sort is applied on one column. If a transaction is applied to update one row, then the group that row sits within will be re-sorted as well as the top level group (as aggregations could impact values at the top level). All of the other 9 groups do not need to have their sorting re-applied.

Deciding what groups need to be operated on within the grid is called Changed Path Selection. After the grid applies all adds, removes and updates from a transaction, it works out what groups were impacted and only executes the required operations on those groups. The groups that were impacted include each group with data that was changed, as well as all parents of changed groups all the way up to the top level.

The example below demonstrates Changed Path Selection. The example is best viewed with the dev console open so log messages can be observed. Note the following:

  • The 'Linux Distro' column is sorted with a custom comparator. The comparator records how many times it is called.
  • The Value column is aggregated with a custom aggregator. The aggregator records how many times it is called.
  • When the example first loads, all the data is set into the grid which results in 171 aggregation operations (one for each group), approximately 48,000 comparisons (for sorting all rows in each group, the number of sorts differs slightly dependent on the data values which are random in this example) and 10,000 filter passes (one for each row). The number of milliseconds to complete the operation is also printed (this value will depend on your hardware).
  • Select a row and click 'Update', 'Delete' OR 'Duplicate' (duplicate results in an add operation). Note in the console that the number of aggregations, compares and filters is drastically fewer. The total time to execute is also drastically less.
  • The property suppressAggAtRootLevel=true to prevent the grid from calculating aggregations at the top level.

Note that Header Checkbox Selection is not turned on for the example above. If it was it would slow the grid down marginally as it requires each row to be checked (for selection state) between each update. If you need a blazing fast grid managing rapid changes, consider avoiding this feature.

Suppress Model Updates

Sometimes it's required to do transaction updates and not have the rows re-sort / re-filter / re-group / re-aggregate. This is useful if the user is interacting with the data and you don't want the rows moving.

To prevent sorting, filtering and grouping after an update transaction, set the grid property suppressModelUpdateAfterUpdateTransaction=true.

Not that this property is only used when transactions are applied that only have updates. If the transaction contains any adds or removes, the sorting, filtering and grouping will always be applied.

The example below is identical to the previous example except suppressModelUpdateAfterUpdateTransaction=true. Note the following:

  1. When data is updated (Update buttons), the grid does not re-execute sorting, filtering or aggregation.
  2. When data is added (Duplicate button) or removed (Remove button), the grid does execute sorting, filtering and aggregation.
  3. After data is updated, hitting Update Model gets the grid to sort, filter and aggregate.