Computed observable dependencies problem...

156 views
Skip to first unread message

mathias....@gmail.com

unread,
Sep 2, 2012, 10:04:15 AM9/2/12
to knock...@googlegroups.com
Hi,
please consider the following case:

function AppViewModel() {
var self = this;

self.boolean1 = ko.observable(false);
self.boolean2 = ko.observable(true);
self.andResult = ko.computed(function () {
return self.boolean1() && self.boolean2();
});
}

Only advanced users undersand why the computed is NOT updated when boolean2 is changed.
The workaround is of course : 

function AppViewModel() {
...
self.andResult =  ko.computed(function () {
var b1 = ko.boolean1();
var b2 = ko.boolean2();
return b1 && b2;
});
}

but it's a little tricky...

I'd suggest for that situation the possibility to declare explicitly the dependencies (not breaking syntax and "AMD like" style) :

function AppViewModel() {
...
self.andResult = ko.computed([this.boolean1, this.boolean2], function () {
return this.boolean1() && this.boolean2();
});
}

and for extended syntax : 

function AppViewModel() {
...
self.andResult = ko.computed({
readDependencies: [this.boolean1, this.boolean2],
read: function () {
return this.boolean1() && this.boolean2();
}) 
});
}

What do you think?
Mat

rpn

unread,
Sep 2, 2012, 9:50:18 PM9/2/12
to knock...@googlegroups.com, mathias....@gmail.com
Hi Mat-
I would not disagree that it can be confusing to understand that dependencies can change in a computed observable.  I think that you could write a wrapper that adds your dependencies array for some cases.  Many times though you don't know all of the things that will be dependencies and the dependencies are not static.

The thing that I have always found interesting about the way that dependencies are tracked in computeds is that for the most part "it just works out".  For example, in your scenario the computed really does not need to ever be triggered until boolean1 becomes true.  The value of boolean2 is not important until the code can reach it.  This makes it pretty efficient, as you only track the dependencies that you really need.

However, if you are subscribing to this computed observable or using it to trigger other actions and you expect it to perform those actions when boolean2 changes, then you do need to understand how the dependencies work.

So, I think that in most cases you are better off not providing static dependencies, although I can see how it is a bit confusing and in some scenarios a wrapper that provides your functionality could come in handy.

Casey Corcoran

unread,
Sep 2, 2012, 11:39:37 PM9/2/12
to knock...@googlegroups.com
Hi everyone, I've built a few paginated menu uis lately and I've been working on this binding:


It basically allows you to iterate over a list of items while grouping them together based on how many rows and columns you specify (rather than one long list of children)

Anyway, using ko.applyBindings repeatedly feels like a no-no, although it's plenty fast.

Is there a more ninja way to do it, or is applyBindings fine for this type of thing?

Thanks!

Casey Corcoran

rpn

unread,
Sep 3, 2012, 12:06:20 AM9/3/12
to knock...@googlegroups.com
At first glance, it does not seem like you will run into problems using that method.  However, two quick things:

-when clearing the nodes, you should call ko.removeNode(element.firstChild) in your loop.  This will do some clean up of the previous bindings for you.

-I would append the nodes prior to calling ko.applyBindings. The computed observables used to track dependencies in bindings will dispose themselves if they determine that their element is not part of the document. This disposal can be triggered if you bind against something and then that binding is triggered again in the act of binding the rest of the elements in that applyBindings call.  Kind of rare, but it does happen occasionally when you bind against a value and then have a select with the options/value bindings that may write to that value immediately.


Hope that helps.

-Ryan

Casey Corcoran

unread,
Sep 3, 2012, 12:11:00 AM9/3/12
to knock...@googlegroups.com
Thanks Ryan, have a great Labor Day!

Casey Corcoran
Reply all
Reply to author
Forward
0 new messages