由于数据是通过AJAX加载的,我需要在数据到达时更新数据。
在页面加载时,我在数据库中收集项目。然后根据选择的项目(self.SelectedProject)加载任务和标签的数据。
self.Projects = ko.observableArray();
self.Tasks = ko.observableArray();
self.Tags = ko.observableArray();
self.SelectedProject = ko.observable(); // Chosen Project-object...
对于初始化,我加载第一个项目的数据:
self.SelectedProject(self.Projects()[0]); // Choose first returned Project...
然后我继续填充我的标记帮助数组:
ko.computed(function () {
// must be ko.computed as else will not update when data arrives for Tags and Tasks (which are likely to be empty at load time)...
// Empty projectAvailableTags before refill...
self.SelectedProject().projectAvailableTags([]);
// First populate current project's "projectAvailableTags"-array with values...
for (var j = 0, jlen = self.Tags().length; j < jlen; j++) {
self.SelectedProject().projectAvailableTags().push(self.Tags()[j].TagName());
}
for (var i = 0, ilen = self.Tasks().length; i < ilen; i++) {
//---- Populate each TaskTag-array with Tags...
for (var j = 0, jlen = self.Tags().length; j < jlen; j++) {
if (self.Tags()[j].TagTaskId() === self.Tasks()[i].TaskId) {
self.Task()[i].TaskTags.push(self.Tags()[j]);
// Populate the different tag-Arrays...
var tagtype = self.Tags()[j].TagType;
switch (tagtype()) {
case 0: self.Tasks()[i].Location().push(self.Tags()[j].TagName()); break;
case 1: self.Tasks()[i].Manager().push(self.Tags()[j].TagName()); break;
case 2: self.Tasks()[i].Employee().push(self.Tags()[j].TagName()); break;
}
}
}
};
});
这可能看起来很奇怪,也许我这样做会不必要地复杂化。 我使用http://aehlke.github.com/tag-it/作为标记管理器,它只需要一个包含TagNames的数组。因此我还没想出如何直接使用Tags() - 数组,尽管我喜欢这样。
任务以手风琴形式呈现,我希望在内容面板中应用Task-tags,而我使用Project-tags作为自动完成功能的tagSource ......
但是我无法弄清楚为什么我的标签应用了ko.computed应用了2次而它们没有被应用,除非我重新选择没有它的项目。
答案 0 :(得分:1)
我认为你有点忽略了计算可观测量的重点。计算的observable和常规函数之间唯一真正的区别是,你可以绑定到一个计算的observable,并在它的一个组件发生变化的任何时候依赖它来自动更新。
计算的observable的example in the knockout documentation使用名/姓,这是一个很好的例子。
基于此,更新计算本身内的计算机的依赖性确实不是一个好主意。在淘汰赛的早期版本中,这实际上会创建一个无限循环引用。
我假设计算机正在运行两次,因为标签和任务都在接收新数据,这会触发更新(但由于敲除中内置的安全措施,只有一次更新)。
更好的选择是订阅SelectedProject。然后,每次可观察到的更改,您都可以重新安装所有阵列。
self.SelectedProject.subscribe(function(newValue) {
<load your arrays here>
});