Inability to bind a custom knockout when calling a default knockout binding

Overview

When I create a custom knockout binding containing a default knockout call for a knockout, my custom binding stops working after the first call.

To see the problem, in the JSFiddle example , change the selected item in ddl once. The text changes as expected. Change it again and nothing will happen. To fail.

More details

I see some odd behavior when extending the default knockout binding " html " with my own "htmlFade" binding. The behavior I'm looking for is the same as html binding , but with fade jQuery animation to fade out DOM elements.

Code examples below. A complete JSFiddle example can be seen here.

HTML looks like this:

<select data-bind="options: names, value: selectedName"></select> <data-bind="htmlFade : selectedName" class="main"></div> 

Json Data is as follows:

 var viewModel = { names: ko.observableArray(['Bob', 'Jon']), selectedName: ko.observable('Bob') }; 

Custom binding is as follows:

 ko.bindingHandlers.htmlFade = { init: function(element, valueAccessor) { ko.bindingHandlers.html.init(); $(element).hide(); }, update: function(element, valueAccessor) { $(element).fadeOut(700, function() { ko.bindingHandlers.html.update(element, valueAccessor); $(element).fadeIn(700); }); } }; 

I intentionally delay the default html handler with the line "ko.bindingHandlers.html.update (element, valueAccessor)" because my goal is to extend the behavior, not recreate it.

The Problem I have is that the above code works the first time I select a select list. After that, he fails.

I created another JSFiddle example , where instead of extending the behavior, I recreated it by adding the following line: "http://jsfiddle.net/jamshall/kYwEE/1/" (copied from the knockout source for html binding by default ) instead of the above html call .update. This seems to be normal.

My question is , why does my custom binding stop working after the first call, when I turn on the default binding call with it? Or, to make it simple, why is JSFiddle1 not working, but JSFiddle2 is working?

Thanks for any help

+4
source share
1 answer

You can come up with the update function for a custom binding, for example, for a computed observable (knockout uses calculated observables to track dependencies when performing bindings on an element). Thus, in your user binding, you do not capture the dependency on the observable that you are associated with, because your code runs asynchronously.

In your update you probably want to do something like:

 update: function(element, valueAccessor) { //just grab dependency ko.utils.unwrapObservable(valueAccessor()); $(element).fadeOut(700, function() { ko.bindingHandlers.html.update(element, valueAccessor); $(element).fadeIn(700); }); } 

So, we just get access to the observable value to capture the dependency. ko.utils.unwrapObservable simply safely handles the extraction of a value whether it is invisible or observable.

Updated example: http://jsfiddle.net/rniemeyer/6UtsP/10/

+1
source

Source: https://habr.com/ru/post/1443257/


All Articles