I'm trying to show a notification DIV using acustom binding, while also adjusting that DIV's CSS and HTML via 2 observables.
The problem is that when I change value of those 2 observables, it also fires the custom binding as well for some reason.
Template:
<div class="alert top-alert" data-bind="fade: topMessageShow, css: topMessageType, html: topMessage"></div>
Custom Handler:
ko.bindingHandlers.fade = {
update: function resolveFade(element, valueAccessor, allBindingsAccessor) {
if (ko.utils.unwrapObservable( valueAccessor() )) {
$(element).hide().delay(300).fadeIn('slow');
} else {
// fade out the notification and reset it
$(element).fadeOut('slow', function() {
// reset those 2 observables that set class and HTML of the notification DIV
MyClass.topMessageType('');
MyClass.topMessage('');
});
}
}
};
Triggering Code:
MyClass.topMessageType('alert-info');
MyClass.topMessage(msg);
MyClass.topMessageShow(true);
JSFiddle: http://jsfiddle.net/UrxXF/1/
This is related to the fact that all bindings fire together on a single element. Here is a post that describes the current behavior: http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html. This is actually changing in KO 3.0 where bindings are maintained independently on an element.
One choice that you could use for now is to set up your own computed
in the init
function like:
ko.bindingHandlers.fade = {
init: function resolveFade(element, valueAccessor, allBindingsAccessor) {
ko.computed({
read: function() {
/your logic goes here
},
disposeWhenNodeIsRemoved: element
});
}
};
With this technique you are simulating the update
function, but allowing it to act independently from the other bindings on the element. The only minor drawback is that you would currently not get any dependencies from observables that are unwrapped in the binding string (like fade: topMessageShow()
rather than fade: topMessageShow
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With