我根据示例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后停止工作
答案 0 :(得分:3)
我已经更新了rniemeyer非常有用的jsfiddle来修复滚动条错误。在原始版本中,尝试添加20行然后使用垂直滚动条,您将看到UI问题。问题是滚动窗格错误地计算了视图大小,因此滚动条会抖动。
这是更新版本。
编辑:Knockout和slickgrid已经更新,所以我更新了小提琴: 编辑:再次:
请注意以下事项:
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 :)只是在绑定期间添加了一些选项。