Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cache computed values with knockout

Lets say I would like to create a function that loops all the elements in an array (observableArray) and return the appropriate item from the array.

I was thinking of creating a computed function to handle this, and using ko.utils.arrayFilter to do the filtering.

Should I cache this action? Or does the computed or the arrayFilter do it internally?

like image 709
IgalSt Avatar asked Aug 19 '12 11:08

IgalSt


1 Answers

The values of computed observables are cached. Their value is only calculated initially and whenever a dependency changes. So, you can access that computed's value over and over again and always receive the cached value.

Based on your comments, it sounds like you want to create computed observables based on certain arguments. A couple considerations with that technique:

  • The bindings for a single element are executed inside of a computed observable to track dependencies. That means that if you only want to use your filter in your UI, then you can actually avoid creating a computed observable and just call a filter function directly. Whenever a dependency changes, your bindings will fire and the function will run again. This would not be the best solution, if you want to also programmatically interact with the filtered data. Here is a sample: http://jsfiddle.net/rniemeyer/QSgPz/

  • If you are going to use this concept frequently, then you could even extend observableArrays to call the filter directly off of an observableArray like: http://jsfiddle.net/rniemeyer/VhCVc/

  • As an alternative, if you have a function that returns a computed itself, then you want to make sure that you are only calling it once for each filter computed that you need. You would not want to call it from a binding where it would get re-created each time the binding fired (unless you had a custom binding that handled it in the init properly). Here is a sample: http://jsfiddle.net/rniemeyer/JrHnT/. Again you could extend observableArrays to be able to create a computed for you if you would use this often.

So, if you are only using this from bindings, then you can choose to skip the computed and just use a function, as the binding uses its own computed observable. If you need to interact with it from your view model, then you would likely want to create the filters there.

like image 140
RP Niemeyer Avatar answered Sep 18 '22 13:09

RP Niemeyer