I've spent the last 6 hours trying to solve this issue, and I can find so little documentation on how subscriptions in Knockout.js work, that it's now moved into from the "mildly annoying" category to "downright frustrating".
What am I trying to accomplish?
I need to animate a portion of the DOM so that it slides up and down as required. Here's the general structure of the DOM that gets animated in this manner:
<section id="add" class="manageOption">
</section>
<section id="replace" class="manageOption">
</section>
<section id="remove" class="manageOption">
</section>
Each .manageOption
has the same size and dimensions and looks very similar. I have an observable in my ViewModel called self.managementState
, which is initially set to false
. A click binding on an irrelevant element sets this observable to either false if none of them are displayed or add / replace / remove depending on which one should be displayed. Only one .manageOption
can be shown at a time.
However, a slideUp or slideDown effect should only occur if self.managementState
is either going from false
or to false
. Therefore, I need to know not only the current value of self.managementState
but also the previous one. If the value changes from add
to remove
, I don't need to animate the elements, the change will occur instantly.
What I have tried
To solve this, I've been wanting to build a custom binding called slideSwitcher
that operates using the above logic I've described, and I also found that this portion of code supposedly fetches the previous value of an observable:
function subscribeToPreviousValue(observable, fn) {
observable.subscribe(fn, this, 'beforeChange');
}
But I can't get it to play nicely in my update
function inside my custom binding, it always returns the wrong result (false has changed to false, for example).
ko.bindingHandlers.slideSwitcher = {
update: function (element, valueAccessor) {
var observable = valueAccessor();
var currentVal = ko.utils.unwrapObservable(valueAccessor());
subscribeToPreviousValue(observable, function (previous) {
console.log('value changed from', previous, 'to', currentVal);
});
}
}
Fundamentally, this is because I simply don't understand the concept of a 'subscription' and I have very little experience writing bindings myself. How can I use the subscription function above to track the previous value of an observable, and how should I structure my binding to achieve what I need?