我正在使用Knockout 3来构建呈现为表格的可编辑网格。网格由Row对象组成,每行一个。在一行内是一个单元格数组(每列一个),然后在每个单元格内部是一个或多个Slot对象。插槽在表格单元格中呈现为一个列表。
外部行定义了一个RowIndex observable,其中的Cells有一个计算的observable,它读取行的RowIndex,而Slots有一个计算的observable,它从Cell中读取RowIndex。
问题在于,当我在一行上设置一个新的RowIndex时,它会传播到Cell,但是当Cell包含Slots时,KO会抛出一个异常:“对象[object object]的未捕获的TypeError:属性'回调'是不是“在knockout-3.0.0.debug.js第1021行的功能”。从Chrome开发者工具中,我看到订阅的callback
属性确实未定义。
如果Cell不包含任何插槽,则在Row上设置RowIndex会导致它传播到Cell而没有问题。
var Row = function(data) {
var self = this;
this.Cells = [];
this.RowIndex = ko.observable(data.rowIndex);
// omitted code...
}
var Cell = function(data, row) {
var self = this;
this.row = row;
this.Enabled = ko.observable(true);
// When row is disabled, disable the cell
row.Enabled.subscribe(function (value) {
if (value == false) {
self.Enabled(false);
}
});
// RowIndex comes from parent row
this.RowIndex = ko.computed(function () {
return self.row.RowIndex();
}, this);
// omitted code ...
}
var Slot = function(data, cell, enabled) {
var self = this;
this.cell = cell;
// RowIndex is cells's RowIndex
this.RowIndex = ko.computed(function() {
return self.cell.RowIndex();
}, this);
// Any change marks slot as dirty
self.Title.subscribe(this.updated);
self.SeatCount.subscribe(this.updated);
self.RowIndex.subscribe(this.updated);
this.updated = function() {
if (self.Action() == actions.None)
{
self.Action(actions.Update);
}
}
// When cell is disabled, I feel disabled, too.
cell.Enabled.subscribe(function(value) {
if (value == false) {
self.Enabled(false);
}
});
// omitted code
}
var ViewModel(colHeadings, rowHeadings, slots) {
var self = this;
// Code omitted to iterate the slots and build the rows
// and cells
// Invoked on a click to add a row at index
this.addRow = function(index) {
var row = new Row({ heading: "New Row", rowIndex: index });
for (var ci=0; ci<this.columnCount; ci++) {
var c = new Cell({ colIndex: ci }, row);
row.Cells.push(c);
}
self.RowData.splice(index, 0, row);
self.renumberRows();
};
// Invoked on a click to remove (disable) a row
this.removeRow = function(row) {
row.Enabled(false);
self.renumberRows();
};
// Sequentially number the enabled rows
this.renumberRows = function() {
var index = 0;
for (var ri=0; ri<self.RowData().length; ri++) {
var row = self.RowData()[ri];
if (row.Enabled()) {
row.RowIndex(index);
index++;
}
}
};
}
当我在ViewModel上通过addRow
插入新行时,会分配RowIndex,并将其传播到Cells。这太好了。但是新的Row的单元格还没有任何插槽,所以到目前为止没有错误。但是我必须重新编号行,以便RowIndex是顺序的。一旦我在一个Row上设置了RowIndex,并且Cell有一个Slot,我就会得到异常。 removeRow
也是如此。
答案 0 :(得分:3)
问题在于,您已在undefined
的此部分代码中使用Slot
回调创建了手动订阅:
// Any change marks slot as dirty
self.Title.subscribe(this.updated);
self.SeatCount.subscribe(this.updated);
self.RowIndex.subscribe(this.updated);
this.updated = function() {
if (self.Action() == actions.None)
{
self.Action(actions.Update);
}
}
正如您所看到的,您在分配之前使用的是this.updated
。那么它就是undefined
。