Search code examples
javascriptknockout.jsslickgrid

SlickGrid w/ DataView not immediately reflecting changes in underlying data


I have the following code that builds a grid using slickgrid.js.

var grid;
var gridDataview;
var gridOptions = {
    enableCellNavigation: true,
    enableColumnReorder: true,
    forceFitColumns: false,
    topPanelHeight: 25
};

function createGrid(data) {
    gridDataview = new Slick.Data.DataView({ inlineFilters: true });
    grid = new Slick.Grid("#grid", gridDataview, data.columns, gridOptions);
    grid.setSelectionModel(new Slick.RowSelectionModel());
    var pager = new Slick.Controls.Pager(gridDataview, grid, $("#pager"));
    var columnpicker = new Slick.Controls.ColumnPicker(data.columns, grid, gridOptions);
    grid.onSort.subscribe(function (e, args) {
        sortdir = args.sortAsc ? 1 : -1;
        sortcol = args.sortCol.field;
        // using native sort with comparer
        // preferred method but can be very slow in IE with huge datasets
        gridDataview.sort(comparer, args.sortAsc);
    });

    // if you don't want the items that are not visible (due to being filtered out
    // or being on a different page) to stay selected, pass 'false' to the second arg
    gridDataview.syncGridSelection(grid, true);
    $("#gridContainer").resizable();
}

I am using this with knockout-js and initially only create the grid after the user makes a selection from a listbox, at which point i fetch data from an rest service and build the grid. each subsequent user selection will not create the grid, only update the data.

    self.selectedInstrument.subscribe(function (newValue) {
    $.getJSON('/data/' + self.selectedCategory().id + '/' + newValue.id, function (data) {
        self.cotData(data);
        if (grid == null) {
            debugger;
            createGrid(data);
        }
        //gridDataview.beginUpdate();
        gridDataview.setItems(data.data);
        //gridDataview.endUpdate();
    });
});

What's happening is: 1. when the grid is initially create, no data is shown, just the column headers. if i move re-order a column header, then the data is shown. 2. If i sort a column, the sort is not visibly reflected. if i start scrolling, then i see the sort being reflected. 3. if i add a grid.render() to the end of the subscription handler above, i do see the data immediately, but then i'm not able to vertically scroll any longer. things seem badly broken at this point.

Any thoughts on what may be happening here? This started happening after i modified the code to create a DataView rather than loading the data right into the grid immediately. I need a DataView because i want to allow sorting and later different types of aggregation and groupings.

Is this possibly related to usage of slickgrid with knockout js?

Thanks much


Solution

  • Not sure why yet, as i'm still feeling my way around SlickGrid, but i had to add the following two subscriptions. the first allowed the grid to display rows immediately when new data is loaded and the second solved a similar issue, but when sorting:

    // wire up model events to drive the grid
    gridDataview.onRowCountChanged.subscribe(function (e, args) {
        grid.updateRowCount();
        grid.render();
    });
    gridDataview.onRowsChanged.subscribe(function (e, args) {
        grid.invalidateRows(args.rows);
        grid.render();
    });