我想为我所有的viewmodels做一个基类,因此我可以检查root-vm上的“isDirty”并让它检查vms的整个树(同时避免循环依赖)。推迟评价?
当我这样做时,我意识到ko属性的顺序非常重要,因为计算属性根据创建属性时存在的其他属性设置其订阅。所以,如果我把一个isDirty计算的像一个基类,将它实际上还要考虑即使存在属性之前总是初始化下面的一个。总之,要长话短说,我发现我可以使用deferEvaluation来解决这个问题。
我的问题是:
有没有对所有的计算性能使用deferEvaluation的任何缺点?为什么默认情况下这种行为是真实的?我什么时候需要将它设置为false?
我能做到这一点isDirty属性更好?任何有关改进或以其他方式进行的建议?
另外,是否有任何方法显式禁用计算属性的初始化,直到创建具有其所有属性的整个对象,然后以某种方式运行它。我的意思是我的唯一问题是,订阅成立之前,所有属性都到位。
注:我使用的是KO精简版工具脏跟踪
function ViewModel() {
var self = this;
self.isDirty = ko.computed(function() {
for (var p in self) {
if (self[p].isDirty) {
if (self[p].isDirty()) return true;
}
else if (self[p].subscribe && self[p].push) { // assuming ko.observableArray
for (var i = 0, j = self[p]().length; i < j; i++) {
if (self[p]()[i].isDirty) {
if (self[p]()[i].isDirty()) return true;
}
}
}
}
return false;
}, this, { deferEvaluation: true });
}
注:只注意到,如果我有一个是取决于isDirty另一个计算财产这个代码将会失败。这是预料之中的,但也是不幸的。如果我可以延迟并强制所有订阅创建对象,那将是一件好事。
我最终在每个类构造的末尾使用了一个endInit方法。我还必须提供调用endInit的类的显式名称,以便只有继承链的“最顶级”类实际上在执行endInit。这不是理想的,但它的工作原理。 – 2013-05-07 14:39:43