通过dependentObservable使用Knockoutjs更新SlickGrid

时间:2011-10-12 15:47:49

标签: knockout.js slickgrid

我根据示例http://jsfiddle.net/rniemeyer/A9NrP/

将SlickGrid与knockout.js一起使用

我按照示例填充网格和添加按钮。我遇到的问题是当我通过ko.dependentObservable更新我的viewmodel的rows属性时,ko.bindingHandlers的'update'部分被触发但是光滑的网格没有获取更改。

定义绑定的html:

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

SlickGrid代码(与示例相同):

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();
    }
}

我的模特:

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));  
},

}

进行ajax调用的代码,并触发ko.bindingHandlers.slickGrid.update但slickgrid似乎没有获取更改,ajax确实返回有效数据,并在用户单击链接时触发:

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

为什么addItem函数有效但ko.bindingHandlers.slickGrid.update不起作用?在更新功能中,我可以看到网格应该绑定的正确数据。 是因为行属性中的所有数据都被覆盖了吗?

更新: 我试过使用grid.invalidate();但它不起作用,并且还看到addItem函数在执行ko.dependentObservable后停止工作

3 个答案:

答案 0 :(得分:3)

我已经更新了rniemeyer非常有用的jsfiddle来修复滚动条错误。在原始版本中,尝试添加20行然后使用垂直滚动条,您将看到UI问题。问题是滚动窗格错误地计算了视图大小,因此滚动条会抖动。

这是更新版本。

编辑:Knockout和slickgrid已经更新,所以我更新了小提琴: 编辑:再次:

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

请注意以下事项:

grid.resizeCanvas(); 

答案 1 :(得分:2)

我遇到了同样的问题并找到了解决方案,将更新代码更改为以下内容:

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();
    }

顺便说一下,setData中的true参数表示你是否希望网格滚动回到顶部。

答案 2 :(得分:1)

在我的情况下,我需要使用slickgrid和knockout与另一个绑定到不同控件的视图模型。我以http://jsfiddle.net/hlascelles/5ddNM/为例,修复了一些问题。使用http://jsfiddle.net/Schnapz/z4YLD/2/或查看下面的说明。

声明网格,Item和viewModel,您可以按照示例中的说明离开。但是,绑定应该适用于所有模型,包括viewModel本身(在pageLoad中调用它或者):

ko.applyBindings();

addItem应如下所示:

addItem: function () {
    viewModel.items.push(new Item(0, "New", 5.00));
},

因为使用'this'在这里不起作用。

然后,自定义绑定器应该如下所示(来自另一个示例的令牌):

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();
    var data = ko.utils.unwrapObservable(settings.data); //just for subscription
    grid.setData(data, true);
    grid.resizeCanvas(); // NB Very important for when a scrollbar appears
    grid.render();
}

}

另外,我遇​​到了添加元素的问题,但我看不到结果。经过一些研究,slickgrid的资料我发现了这个解决方案:

<div id="grid" class="grid-canvas" data-bind="slickGrid: { 
                                                        data: viewModel.items, 
                                                        columns: viewModel.columns, 
                                                        options: { 
                                                                    enableColumnReorder: false,
                                                                    rowHeight: 20, 
                                                                    enableAddRow: true,
                                                                    autoHeight: true
                                                                 } }"></div>
<a href="#" class="btn-link" data-bind="click: viewModel.addItem">Add Item</a>

因为某种方式默认情况下grid-viewport的高度为0px :)只是在绑定期间添加了一些选项。