2

Hi is there a way to not fire the function when instantiating a ko.computed

example is

i have this ko.computed

ko.computed(function(){ alert(this.Test); } , this);

so basically if i instantiated this computed this will fire the function defined there is there a way not to fire it upon instantiation? and only fire it when dependency change?

Don
  • 131
  • 1
  • 10

2 Answers2

5

You need to set the deferEvaluation option:

deferEvaluation — Optional. If this option is true, then the value of the computed observable will not be evaluated until something actually attempts to access its value or manually subscribes to it. By default, a computed observable has its value determined immediately during creation.

ko.computed(function(){ alert(this.Test); } , this, { deferEvaluation: true });
nemesv
  • 138,284
  • 16
  • 416
  • 359
  • yeah i tried this but it doesn't evaluate if the dependencies of the computed has been updated – Don Mar 30 '17 at 10:09
  • 2
    Maybe you haven't assigned the computed object to any html element? – muhihsan Mar 30 '17 at 10:32
  • @Don if you are using `deferEvaluation` the dependency tracking only "starts" when you first access your computed (by getting its value or subscribing to it). So that is not working that you don't evaluate your computed and then trigger a dependency because the Computed is not evaluated so it does not know about the fact that it has a dependency. – nemesv Mar 30 '17 at 10:39
  • @Don if you haven't assigned the computed to any html elements but you still want it to update when the dependencies change then what you really need is a subscription to the dependent observables and not a computed. – Jason Spake Mar 30 '17 at 15:42
3

You can also use a knockout pureComputed for this. A pure computed only evaluates when there's a dependency.

Example:

var person, fullName,
    getFullName = function() { 
       return person().firstName() + " " + person().lastName();
    };

person = ko.observable(null);

// This won't work, because the computed evaluates and getFullName doesn't 
// check for `null`
try {
  fullName = ko.computed(getFullName);
} catch (err) {
  console.log("Regular computed:");
  console.log(err.message);
}

// This will work because there's no dependency to `fullName` yet
// At `applyBindings`, `fullName` needs to be evaluated
fullName = ko.pureComputed(getFullName);

person({
  firstName: ko.observable("Jane"),
  lastName: ko.observable("Doe")
});

ko.applyBindings({ heading: fullName })
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<h3 data-bind="text: heading"></h3>  
user3297291
  • 22,592
  • 4
  • 29
  • 45