我也遇到过这个问题,这实际上是由于 TypeScript 生成 JS 的方式造成的。
在普通的JS中,你可以这样做:
new kendo.ObservableObject({
items: []
});
并且构造函数会自动包装items[]
进入一个新的ObservableArray
为你。
然而,该行为在 TypeScript 中失败,因为代码:
export class ViewModelSample extends kendo.data.ObservableObject {
Items: kendo.data.ObservableArray = [];
constructor() {
super();
}
实际上会生成类似以下内容的内容:
function ViewModelSample() { // constructor
_super.call(this); // call to ObservableObject constructor (super())
this.Items = []; // add Items to this.
}
So the Items
属性不会添加到 ViewModel 直到之后ObservableObject
构造函数被调用,所以 Kendo 不知道它,并且不会将其包装到ObservableArray
.
该顺序与 Kendo 对正常 JavaScript 的期望正好相反。
@Anzeo 建议手动将项目初始化为ObservableArray
大部分都会起作用
Items: kendo.data.ObservableArray = new kendo.data.ObservableArray([]);
然而 ObservableArray 的parent
不会正确设置为 ViewModel,因此有时如果您尝试 MVVM 在 ListView 模板内的 ViewModel 上绑定一个函数或属性,该模板会绑定到Items
,它将无法找到 ViewModel 上的属性或函数。
您可以通过在开发工具控制台中执行此操作来证明这一点:
x = new kendo.data.ObservableObject({
items: []
});
x.items.parent(); // returns the object 'x' (correct)
y = new kendo.data.ObservableObject();
y.items = new kendo.data.ObservableArray([]);
y.items.parent(); // return undefined (but should be the object 'y')
这实际上是 TypeScript 带来的阻碍多于它的帮助......
正确的解决方案是对类变量进行初始赋值inside你的构造函数,在调用之前super()
.
class ViewModelSample extends ObservableObject {
Items: kendo.data.ObservableArray;
constructor() {
this.Items = [];
super();
}
}
它以正确的顺序生成 JS:
function ViewModelSample() {
this.Items = []; // Items assigned before call to ObservableObject constructor
_super.call(this);
}
有趣的是,typescriptlang.org 上的游乐场似乎并不关心这一行:
this.Items = [];
将数组分配给应该类型的变量ObservableArray
,但是如果真正的编译器抛出错误,那么你也可以这样做
this.Items = new kendo.data.ObservableArray([]);
那应该有效。生成的JS只要添加Items
之前的对象的属性ObservableObject
构造函数被调用。