如何制作ko.computed触发器

时间:2014-12-12 14:38:58

标签: jquery knockout.js

我有这个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/

任何提示和建议都受到高度赞赏。

4 个答案:

答案 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;
        });
在计算的开头

做了伎俩。