我有这个ko.computed:
ko.computed(function () {
var index = 0;
ko.utils.arrayForEach(self.Scenes(), function (scene) {
var jcount = 0;
scene.sequenceNo(); // I thought this would trigger it, but it doesn´t!
ko.utils.arrayForEach(scene.Textbatches(), function (batch) {
batch.sequenceNoInProject(index);
batch.sequenceNo(jcount);
index++;
jcount++;
});
});
});
,其中
Scene = function (data) {
var self = this;
//...
self.sequenceNo = ko.observable(data.sequenceNo);
self.Textbatches = ko.observableArray(); // Array holding allocated text bathes
};
和 self.Scenes被创建为一个Scene-instances数组。
我想要的是分配给要计算的场景的textbatches的sequenceNo a)文本批次被拖动(这是有效的) b)以新的顺序重新排列场景(拖放顶部的第二个场景)。
b)不起作用,我的想法是,当self.Scenes()。sequenceNo()的值改变时,ko.computed应该触发...
小提琴:http://jsfiddle.net/AsleG/6xwwuonp/9/
任何提示和建议都受到高度赞赏。
答案 0 :(得分:0)
您可以在计算的observable中添加对trigger()
的调用,该调用将注册对它的依赖:
ko.computed(function () {
var index = 0;
ko.utils.arrayForEach(self.Projects(), function (item) {
var jcount = 0;
item.trigger(); // <-- here
ko.utils.arrayForEach(item.tasks(), function (task) {
task.sequenceNoGlobal(index);
task.sequenceNoLocal(jcount);
index++; jcount++;
});
});
});
答案 1 :(得分:0)
删除括号可能有用(item.tasks)
ko.computed(function () {
var index = 0;
ko.utils.arrayForEach(self.Projects(), function (item) {
var jcount = 0;
ko.utils.arrayForEach(item.tasks, function (task) {
task.sequenceNoGlobal(index);
task.sequenceNoLocal(jcount);
index++; jcount++;
});
});
});
或者,每当您更新任务时,请使用valueHasMutated()。
this.tasks.valueHasMutated();
更好的模式是获取对我们的底层数组的引用,推送到它,然后调用.valueHasMutated()。现在,我们的订阅者只会收到一个通知,表明该阵列已更改。 http://www.knockmeout.net/2012/04/knockoutjs-performance-gotcha.html
答案 2 :(得分:0)
这并没有多大意义,我认为你应该退后一步,先评估你的问题。您可以通过几种不同的方式触发计算,一种方法是将item.trigger()
添加到计算中,并在其外部更改触发器。确保更改,换句话说,指定一个新值。因为如果你总是something.trigger(true)
,它只会在第一次触发计算。
但重点是,计算机会重新计算,但如果它实际上并不依赖于trigger
的值,它将返回相同的结果。如果您的商品tasks
正在发生变化,那么它也会触发,并且依赖性也会有意义。因此要么另外看一下可观察量和计算量是如何工作的,要么提出一个解释问题的方法,如果它比我们假设的更复杂。
答案 3 :(得分:0)
当它浮现在脑海中时,解决方案非常明显。 ko.computed一直触发,但它没有承认self.Scenes() - 数组没有改变,即使它在手风琴中排序并且sequenceNo已更新。
添加
self.Scenes().sort(function(a,b){
return a.sequenceNo() < b.sequenceNo() ? -1 : a.sequenceNo() > b.sequenceNo() ? 1 : a.sequenceNo() == b.sequenceNo() ? 0 : 0;
});
在计算的开头做了伎俩。