Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visualizing dependencies for computed fields in Knockout

Is there a way in knockout.js to determine

  • which values (ko.observable or ko.computed) depend on each other in what way (precedents/dependents) and
  • which HTML nodes (text binding, for starters) depend on the current value1, so I can highlight them on screen.

?

1This implies that I need a way to go from an HTML node to the connected ko.subscribable, not just to the view model, like ko.dataFor() does. This seems to be impossible as well.


I've built a web application that works like a spreadsheet - many numeric values that are based on each other according to a set of business rules. Some of them are calculated, some of them user-provided.

At the moment I'm using my own JS library that does all the dependency tracking and dynamic screen-updating. This works, but I'd like to swap it with knockout.js for added versatility and elegance.

Knockout keeps track of this information somewhere. How can I use it?


For example, imagine a spreadsheet (an HTML table) that sums up a few integers:

  | A  B  C
--+---------
1 | 4  1  5
2 |    2
3 |    3  8
  • When the user clicks on cell B3, I'd like to find out that it depends on B1 and B2 and that C3 depends on it.
  • When the user clicks on cell C3, I'd like to find out that it depends on A1, B1, C1, B2 and B3.
like image 776
Tomalak Avatar asked Jun 18 '12 15:06

Tomalak


2 Answers

This is a very interesting question - and, it seems, not a simple one to answer. I've looked at the knockout source and it looks like this data is stored in the _subscriptionsToDependencies property, but that doesn't seem to publicly exposed.

I did notice getDependenciesCount which is exposed - check out this fiddle to see it in action.

I'm still investigating this, but it seems like it may require a fork of knockout itself unless we can get at the underlying observable. But here's what I've found so far, which you may find helpful:

Running it through the debugger, it seems like at runtime the minified version of knockout renames the _subscriptionsToDependencies property to V. At runtime the getDependenciesCount property's value is : function (){return v.length}

I hope this helps.

Edit: For those who arrive to this question looking for the answer, it does not seem to be possible in KnockoutJS as of version 2.1

like image 45
daedalus28 Avatar answered Oct 04 '22 18:10

daedalus28


I have written a plugin for Knockout (2.0+) whose primary purpose is eliminating duplicate updates for computed observables. But since the plugin replaces the ko.computed object, I have also added the ability to get a list of the dependencies/dependents for observables. Each computed object has a getDependencies method that returns an array of observables, and each observable/computed observable has a getDependents method that returns an array of computed observables.

like image 114
Michael Best Avatar answered Oct 04 '22 20:10

Michael Best