Call standard knockout binding binding from user binding

I would like to create a conditional click binding in KnockoutJS. This is basically standard click binding, as if you were using it in Knockout, but the condition must be met in order for the attached function to be executed. In my case, the best option is to create a custom binding descriptor, in which you then call the standard click binding, if enabled.

ko.bindingHandlers.safeClick = { 'init': function(element, valueAccessor, allBindingsAccessor, context) { $(element).click(function() { if(mycondition == true) { // call the standard click binding here -> this is the part I don't know } }); } } 

I want to replace all my standard click bindings with this custom binding. Therefore, it is important to call click bindings in the right way, so all parameters provided in HTML are passed to the function. For instance:

 <a href="#" data-bind="click: basevm.gotopage.bind($data, '#homepage')">Home</a> <a href="#" data-bind="click: itemvm.activateItem">Activate</a> 

They must be replaced by

 <a href="#" data-bind="safeClick: basevm.gotopage.bind($data, '#homepage')">Home</a> <a href="#" data-bind="safeClick: itemvm.activateItem">Activate</a> 

I would really appreciate it if you could help me with the missing part in the user binding.

+6
source share
2 answers

The correct way to delegate click-through winnings here is as follows:

  • you take your original function (e.g. using valueAccessor() )
  • create a new valueaccessor function in which you will return a new function containing your condition, which then calls your original function. And pass this new value attribute to the click binding.

So your safeClick will look like this:

 ko.bindingHandlers.safeClick = { 'init': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var originalFunction = valueAccessor(); var newValueAccesssor = function() { return function () { if (mycondition == true) //pass through the arguments originalFunction.apply(viewModel, arguments); } } ko.bindingHandlers.click.init(element, newValueAccesssor, allBindingsAccessor, viewModel, bindingContext); } } 

JSFiddle demo.

This will work for the first click, and you do not need to manually subscribe to the click event or fire it using jQuery.

+11
source

You can call it like this:

 ko.bindingHandlers.click.init(element, valueAccessor, allBindingsAccessor, context); 

EDIT: You can mannualy first trigger a click event:

 ko.bindingHandlers.safeClick = { 'init': function(element, valueAccessor, allBindingsAccessor, context) { $(element).click(function() { if(mycondition == true) { ko.bindingHandlers.click.init(element, valueAccessor, allBindingsAccessor, context); } }); if(mycondition == true) { $(element).trigger('click'); } } } 
+1
source

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


All Articles