Updating SlickGrid with Knockoutjs via dependentObservable

Dave picture Dave · Oct 12, 2011 · Viewed 7.4k times · Source

I'm using SlickGrid with knockout.js based on the example http://jsfiddle.net/rniemeyer/A9NrP/

I have the grid populating and the add button working as per the example. The problem I'm having is when I update the rows property of my viewmodel via a ko.dependentObservable the 'update' section of the ko.bindingHandlers is fired but slick grid does not pick up the changes.

html that defines the binding:

<div id="grid" data-bind="slickGrid: { data: rows, columns: columns }"></div>

SlickGrid code (same as the example):

var grid;
ko.bindingHandlers.slickGrid = {
    init: function (element, valueAccessor) {
        var settings = valueAccessor();
        var data = ko.utils.unwrapObservable(settings.data);
        var columns = ko.utils.unwrapObservable(settings.columns);
        var options = ko.utils.unwrapObservable(settings.options) || {};
        grid = new Slick.Grid(element, data, columns, options);
    },
    update: function (element, valueAccessor, allBindingAccessor, viewModel) {
        var settings = valueAccessor();
        // I can see the correct data here but the grid does not update
        var data = ko.utils.unwrapObservable(settings.data);  
        grid.render();
    }
}

my model:

myViewModel = {
data : ko.observableArray(),
tabs: ['High', 'Medium', 'Low'],
rows : ko.observableArray([]),
columns : [
        {
            id: "id",
            name: "ID",
            field: "id"
        },
        {
            id: "Location",
            name: "Location",
            field: "Location"
        },
        {
            id: "Comment",
            name: "Comment",
            field: "Comment"
        }
        ],
addItem: function() { // this works and SlickGrid adds a new row
  this.rows.push(new ModelRow(0, "New", 5.00));  
},

}

The code that make the ajax call, and fires ko.bindingHandlers.slickGrid.update but slickgrid doesnt seem to pick up the changes, the ajax does return valid data, and is fired when the user clicks on a link:

ko.dependentObservable(function () {
   if (this.data.lastAlarmRequest) this.data.lastAlarmRequest.abort();
       this.data.lastAlarmRequest = $.get("/audit/alarmsdata/high", null, this.rows);
}, i2owater.viewmodels.AlarmsForViewModel);

Why does the addItem function work but not the ko.bindingHandlers.slickGrid.update? In the update function I can see the correct data that the grid should be bound to. Is it because all the data in the rows propertys is overwritten?

UPDATE: I've tried to use grid.invalidate(); but it doesnt work and have also seen that the addItem function stops working once ko.dependentObservable is executed

Answer

hlascelles picture hlascelles · Aug 27, 2012

I've updated rniemeyer's very useful jsfiddle to fix a scrollbar bug. In the original, try adding 20 rows then use the vertical scrollbar, and you'll see a UI problem. The issue is that the scrollpane incorrectly calculates the view size, so the scrollbar jitters.

Here an updated version.

EDIT: Knockout and slickgrid have been updated so I've updated the fiddle: EDIT: And again:

http://jsfiddle.net/5ddNM/79/

Note the following:

grid.resizeCanvas();