Controlled object-table

A controlled object-table (<automatic="false">) contains data that is controlled by external code only. It will therefore not handle the pagination, sorting or filtering of data. Instead, you are required to communicate to the component:

  • the amount of pages,

  • what data should display for the current page,

  • and what should happen when the state changes.

When to use a controlled object-table

  • The table represents remote API data

  • When working with Big data

  • Running into performance issues

Implementation

The Showcase: Object Tables template app contains an example implementation of a controlled object-table. Check it out!

Implementing a controlled object-table requires the use of on-state-change, mode="paginate", automatic="false" and the page-count attributes on the object-table.

When a table receives an automatic="false" attribute it will automatically go into controlled mode. The page-count attribute must contain a function which returns the total number of pages, since the component cannot determine the page count in its own.

An on-state-change attribute also needs to be added to record the next state of the object-table for when a page button is selected or filtering gets applied. When this function fires, you should mutate the query passed to the table to represent the new state by means of limiting, sorting and skipping the underlying query.

Here is the full list of steps:

  1. Create a variable to store the initial state and the computed pages

var pages = 1;
var tableState = {
    limit: 10,
    page: 1
}
  1. Use this variable to setup the initial query

// setup the query on view init
function init(){
    refreshQuery();
}

/**
 * This function will use the state to refresh the query
 */
function refreshQuery(){
    // step 1 count the amount of entries so we can work out the number of pages
    var q = DB.users;
    pages = Math.max(1, Math.ceil(q.count() / tableState.limit));

    // step 2 filter the query according to the state
    view.query = q.limit(tableState.limit).skip((tableState.page - 1) * tableState.limit).toArray();
}
  1. Setup a function for when the state changes

function tableStateChanged(state){
    // store the new state
    tableState = state;

    // update the query
    refreshQuery();

    // When computation is complete (if there are multiple controlled tables, only call this after all computations)
    journey.forceDigest();
}
  1. Set the object-table up similar to this example:

<object-table
  query="users"
  page-count="$:pages"
  mode="paginate"
  automatic="false"
  on-state-change="$:tableStateChanged($state)"
>
  ...
</object-table>

Last updated