我正在尝试实现一个HasOpenIssues
计算的 observable,它绑定到一个 UI 元素,如果嵌套的 observableArray 的任何成员满足条件,该元素就会更新,并且无法使其工作。我正在使用 KO 2.2.0。
我的视图模型有一个 observableArray of Visits;每个访问都有一个 observableArray of Issues;每个Issues数组都可以包含Issue的实例,它有一个可观察的IsFixed属性。我还有一个计算出的 observable LatestVisit,它返回Visits数组中的最后一次访问:
function myVM( initialData ) {
var self = this;
var Issue = function( id, isFixed, description ) {
var self = this;
self.Id = id;
self.IsFixed = ko.observable( isFixed );
self.Description = ko.observable( description );
};
var Visit = function( id, visitDate, issues ) {
var self = this;
self.Id = id;
self.VisitDate = ko.observable( visitDate );
self.Issues = ko.observableArray([]);
// init the array
issues && ko.utils.arrayForEach( issues, function( issue ) {
self.addIssue( issue.Id, issue.Fixed, issue.Description );
});
}
Visit.prototype.addIssue = function( id, isFixed, description ) {
this.Issues.push( new Issue( id, isFixed, description ) );
};
self.LatestVisit = ko.computed( function() {
var visits = self.Visits();
return visits[ visits.length - 1 ];
});
... vm continues
所有这些都开始为空,在 I 之前ko.applyBindings()
,我从服务器获取一些初始数据并将其作为参数传递给我的视图模型,它使用它来初始化各种可观察对象:
... continued from above...
self.init = function() {
// init the Visits observableArray
ko.utils.arrayForEach( initialData.Visits, function( visit ) {
self.Visits.push( new Visit( visit.Id, visit.InspectionDateDisplay, visit.Issues ) );
});
... more initialization...
};
self.init();
}
function registerVM() {
vm = new myVM( initialDataFromServer );
ko.applyBindings( vm );
}
因此,在此过程中的某一时刻,我无法观察到LatestVisit
,因为Visits
尚未填充数组,也无法观察到数组,因为尚未填充Issues
其父级。Visit
在我初始化之后,这些结构有数据,我需要更新HasOpenIssues
以反映初始数据的状态。
然后,我允许用户向 中添加新Issues
的LatestVisit
,并将新的或现有的标记Issues
为Fixed
。所以我也需要HasOpenIssues
对这些变化做出反应。
我试图HasOpenIssues
在视图模型的根、Visits
数组、Visit
原型上以及直接在LatestVisit
计算上添加一个计算属性,但没有任何效果。它看起来像这样:
self.LatestVisit().HasOpenIssues = ko.computed( function() {
var unfixed = ko.utils.arrayFirst( this.Issues(), function( issue ) {
return issue.IsFixed == false;
});
console.log('HasUnfixedIssues:', unfixed);
if ( unfixed ) { return true; }
});
如果我让它在初始化之前运行,我会得到一些变化
Uncaught TypeError: Object [object Window] has no method 'Issues'
或者,如果我, root, { deferEvaluation: true }
向计算函数调用添加参数,我会得到
Uncaught TypeError: Cannot set property 'HasUnfixedIssues' of undefined
如果我不使用 (),比如self.LatestVisit.HasOpenIssues
,那么我会得到
Uncaught TypeError: Object [object Window] has no method 'Issues'
如果我不使用延迟选项。如果我添加它,我不会在初始化时收到错误,但是当我更新Issues
后没有任何反应。
关于如何实现这一点的任何建议?
谢谢!