Knockout: computed observable vs function
Asked Answered
E

1

55

When using knockout, what is the advantage of using read-only computed observables rather than simple functions?

Take the following viewmodel constructor and html snippet, for example: ​

var ViewModel = function(){
    var self = this;
    self.someProperty = ko.observable("abc");
    self.anotherProperty = ko.observable("xyz");
    self.someComputedProperty = function(){
        return self.someProperty() + self.anotherProperty();
    };    
};

<input data-bind="value: someProperty"/>
<input data-bind="value: anotherProperty"/>
<p data-bind="text: someComputedProperty()"></p>

Everything here seems to work as you'd expect, so is there a reason why I should instead use:

​var ViewModel = function(){
    var self = this;
    self.someProperty = ko.observable("abc");
    self.anotherProperty = ko.observable("xyz");
    self.someComputedProperty = ko.computed(function(){
        return self.someProperty() + self.anotherProperty();
    });    
};


<input data-bind="value: someProperty"/>
<input data-bind="value: anotherProperty"/>
<p data-bind="text: someComputedProperty"></p>

I notice that the documentation at http://knockoutjs.com/documentation/computedObservables.html states that "...declarative bindings are simply implemented as computed observables", so does that mean there's need for me to use them explicitly in my viewmodels?

Ewens answered 17/7, 2012 at 17:31 Comment(0)
S
76

If the only purpose of your computed observable is to do a simple binding against it, then using a function would be equivalent. Bindings are implemented inside of a computed observable to track the dependencies, so it will re-trigger your binding when any of the observables change.

Here are a few things to consider about computed observables vs. a function

  • the value of a computed observable is cached, so it is only updated when it is created and when a dependency is updated. For a regular function, you would need to execute the logic each time. If many things depend on that value (say each item in a collection is binding against a value from the parent), then this logic will be getting run again and again.

  • in your JavaScript, you are also free to use computed observables like you would other observables. This means that you can create manual subscriptions against them and depend on them from other computeds (calling a function would also create this dependency). You can rely on the normal utility methods in KO like ko.utils.unwrapObservable to generically determine if you need to call it as a function or not to retrieve the value.

  • if ultimately you want to ship the value to the server, a computed observable will naturally appear in your JSON output, while a value that is the result of a normal function will just disappear when converted to JSON (you would have to do more work to populate a property from that function first).

Sherilyn answered 17/7, 2012 at 17:55 Comment(3)
Good answer. I sometimes use a function instead of a computed when I WANT the full logic to be executed every time.Macrae
how does it know that a computed observable depends on another observable, when all i passed it was a function? does it parse that function !? - time to read the knockout source code i guessObjective
the dependencies are determined as the computed is being evaluated. so, the act of accessing an observable's value adds a dependency to the current computed. There is no parsing of the function necessary. Hope that helps!Sherilyn

© 2022 - 2024 — McMap. All rights reserved.