Why is KnockoutJS custom binding triggered?

I have a strange situation. Basically, I have two custom bindings that are used to animate the DOM element for it with a new value. These are aWidth and aRight, which expect width and right values.

I implemented bindings like this:

<div class='classname' data-bind="aRight: right, aWidth: containerWidth, style: { zIndex: zindex, left: (left() + 'px'), height: (containerHeight() + 'px') }"> 

... and user bindings look like this:

  ko.bindingHandlers.aWidth = { update: function (element, valueAccessor, allBindingsAccessor, context) { // Get the value accessor var value = valueAccessor(); // Get the new width and the duration of the animation var newWidth = ko.utils.unwrapObservable(value); var duration = 500; $(element).animate({ width: newWidth }, duration, "swing"); } }; ko.bindingHandlers.aRight = { update: function (element, valueAccessor, allBindingsAccessor, context) { // Get the value accessor var value = valueAccessor(); // Get the new width and the duration of the animation var newRight = ko.utils.unwrapObservable(value); var duration = 500; $(element).animate({ right: newRight }, duration, "swing"); console.log("aRight Called: newRight - " + newRight + ", duration - " + duration); } }; 

So, the problem arises when we change the observable other than my two special observable observables, for example zindex.

If we change the observed zindex, the value will be correctly updated in the DOM, but for some reason my aRight binding also works! ...

I don't have a link to it in my custom aRight binding, so maybe there could be a dependency?

My aRight binding also starts when aWidth binding is also activated, which is also a bit strange!

Does anyone have any ideas about this?

Thanks a lot!

Andy.

Update

This is part of the view model, which updates the index, which when I call my automatic aRight to fire (this, by the way, is a very psudo code!):

  var page = function() { this.zindex = ko.observable(0); this.right = ko.observable(0); // and other observables.... } var viewModel = function() { var pages = ko.oberservableArray(); // populate the pages array etc... this.someMethod = function() { // Do some stuff... this.anotherMethod(); // Do some other stuff } .bind(this); this.anotherMethod() = function { var pageCount = this.pages().length; for (var pageNum = 0; pageNum < pageCount; pageNum++) { var page = this.pages()[pageNum]; page.zindex(/* a different value */); // This is what causes my aRight binding to fire... } } .bind(this); } 

Update

I just read the post here: http://groups.google.com/group/knockoutjs/browse_thread/thread/26a3157ae68c7aa5/44c96d1b748f63bb?lnk=gst&q=custom+binding+firing#44c96d1b748f63bb

Saying:

In addition, the binding will start the update function again if another binding in the same data binding attribute is also triggered.

Does this mean that what I see is that my custom binding is triggered when any other data binding attribute binding is triggered (as it happens, it is possible that zindex is the first thing I see a change)? Isn't that a little weird / wrong? ...

Update

I have a simple violin that I think pretty much sums up my problem. It seems like any binding to the same data binding attribute, as many custom bindings will force it to update!

http://jsfiddle.net/J6EPx/2/

Hmmm ... I think I have to get around this by manually checking my user bindings to see if the value really changed or not! Does this mean that it does not spoil the actual anchor point?

I also posted a more specific question on the Knockout forums: http://groups.google.com/group/knockoutjs/browse_thread/thread/d2290d96e33f1d5a

+6
source share
1 answer

It is currently under design. All bindings in the data binding are triggered when any of the bindings is triggered. This is because they are all wrapped in one dependObservable. In some cases, the bindings are interdependent (if the parameters are updated, then the value must be satisfied to ensure that it is still a valid value). However, in some cases this causes a problem.

There is another pattern that you can use when creating a custom binding that helps mitigate this behavior. Instead of defining the guts of your functionality in the update function, you would actually create your own dependObservable in the init function. It will look like this:

 ko.bindingHandlers.custBinding= { init: function(element, valueAccessor) { ko.dependentObservable({ read: function() { ko.utils.unwrapObservable(valueAccessor()); alert("custBinding triggered"); }, disposeWhenNodeIsRemoved: element }); } }; 

http://jsfiddle.net/rniemeyer/uKUfy/

+8
source

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


All Articles