Reputation: 4779
I found that my bindingHandler causes unexpected pureComputed evaluation delay.
Without binding handler (simply comment the HTML out), I see the following log:
In subscription, new value is (newName), nameComputed is (newNameComputed)
As you can see, in the subscription, the computed was evaluated to the latest value.
With binding handler, I see the following log:
Evaluation in bindingHandler oldNameComputed
In subscription, new value is (newName), nameComputed is (oldNameComputed)
Evaluation in bindingHandler newNameComputed
As you can see, in the subscription, the computed was still using the old value (oldNameComputed), and in the next evaluation it's evaluated to latest value (newNameComputed)
This is unexpected to me -- adding the binding handler changes the evaluation behavior.
nameComputed
and set it in subscription on name
?Adding a bit context. My nameComputed
is actually nameError
which processes the name
and detects whether the input is allowed or has errors (e.g. no special character, nonempty, max length etc).
In the subscription, I wanted to do some ajax calls if there is no name error. So I looked at the value of nameError
and only fires the requests if there is no error.
But with the binding handler, my nameError
check is outdated.
Yes, I do have the latest name
value in the subscription, but I need to call the name error check function again to get the latest nameError
value instead of directly using nameError
computed value.
Upvotes: 1
Views: 68
Reputation: 4779
Credit to mbest in Github Issue
The first section in the pure computed documentation describes its two states. The difference you see in behavior is because the pure computed is in a different state. Without the binding handler, it is in the sleeping state, and with the binding handler, it is in the awake state.
It is normal that a subscription can run while state is being updated, and thus not all computed observables have been updated with the latest value. The main way to work around this is use deferred updates. If you set ko.options.deferUpdates = true;
, you will get the results you want.
I might not go in this route for now because I'm working on a big project and don't want to introduce this global level change for now.
Upvotes: 1