Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating SlickGrid with Knockoutjs via dependentObservable

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

like image 632
Dave Avatar asked Oct 12 '11 15:10

Dave


2 Answers

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(); 
like image 71
hlascelles Avatar answered Oct 23 '22 04:10

hlascelles


I just had the same issue and have found the solution, change your update code to the following:

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.setData(data,true)
        grid.render();
    }

By the way, the true parameter in setData indicates if you want the grid to scroll back to the top or not.

like image 33
Danny Jones Avatar answered Oct 23 '22 05:10

Danny Jones