I'm faced a problem that my computed observable stops triggering after some sequence of dependency changes. Finally I found out the point: if dependency was inside of false branch statement during latest evaluation, computed will not be triggered next time even if condition became true before evaluation finished. Here is a sample: https://jsfiddle.net/sgs218w0/1/
var viewModel = new function(){
var self = this;
self.trigger = ko.observable(true);
self.fire = function(){
self.trigger(! self.trigger());
};
self.content = function(){
var test = 3;
return ko.computed(function(){
alert("triggered!");
if(test !== 0){
console.log(self.trigger());
alert(test);
}
test--;
});
}();
};
ko.applyBindings(viewModel);
Is it bug or feature? Do you know any workaround for this issue? I seems to be optimization, but it looks aggressive and incorrect for me. (Edit: I changed my mind. It is reasonable, but can lead to some issues sometimes. I think knockout should have options to fix this issues)
P.S. I could publish more detailed example of real code to make question more specific, if you need it. But the point of real code it the same.
UPDATE Well, I had to be less lazy to provide more detailed example of what I want achieve. I like the idea of computed which automatically make ajax calls. Described here. One disadventure I see is that call will be made even if corresponding part of UI is invisible. I tried to fix it this way: https://jsfiddle.net/bpr88bp3/1/. The problem is that once tab is deativated it can't be activated anymore, because computed stops triggering...
After reading the update to your question and looking through the updated example code, I've come up with a real solution. This uses a pureComputed
to do the update, taking advantage of the fact that a pure computed can be activated and deactivated by subscribing to it and disposing the subscription. Here is the important code:
updateComputed = ko.pureComputed(function () {
updateTrigger();
result(evaluator.call(owner));
});
ko.computed(function () {
var isActive = result.active();
if (isActive && !updateSubscription) {
updateSubscription = updateComputed.subscribe(function () {});
} else if (updateSubscription && !isActive) {
updateSubscription.dispose();
updateSubscription = undefined;
}
});