Enable condition for click binding

2019-01-24 13:46发布

Is there any way to specify an enable condition for the click binding? For example if I have the following:

<div data-bind="click: toggleDialog">Click Me</div>

I'd like to be able to disable clicking if a specified condition occurs so something to the effect of:

<div data-bind="click: toggleDialog, enableClick: myName() === 'John'">Click Me</div>

I'm thinking maybe a custom binding would work for this, but not quite exactly sure how to go about doing it.

标签: knockout.js
4条回答
Summer. ? 凉城
2楼-- · 2019-01-24 13:59

I've recently done this and put the condition check into the click function itself, so it won't do anything unless the condition is met. I also then use a computed function to provide the css class for the element, and change the cursor dependent on whether the element will react to the click:

In my view model:

iconStyle = ko.computed(function () {
    var cssClass = 'DefaultClass';
     if (/*condition to check if click is valid*/) {
        cssClass = cssClass + ' Off';
     }

    return cssClass;
})

Then bind like this:

<div class="stepIcon" data-bind="click: clickFunction, css: iconStyle"></div>
查看更多
男人必须洒脱
3楼-- · 2019-01-24 14:04

It's actually a good amount simpler than any of these options. You can't make the binding conditional but you can make what function is fired conditional. Just use a conditional in the binding:

<div data-bind="click: myName() === 'John' ? toggleDialog : function(){ /* Nothing Happens */}">Click Me</div>

That will either fire toggleDialog() or an anonymous function(){} that does nothing.

You can even stack bound properties to disable the button itself:

<div data-bind="
    disabled: myName() !== 'John',
    click: myName() === 'John' ? toggleDialog : function(){ /* Nothing Happens */}
">Click Me</div>

Or have another function that runs in response to an unmet condition:

<div data-bind="
    disabled: myName() !== 'John',
    click: myName() === 'John' ? toggleDialog : tellUserTheyAreWrong
">Click Me</div>

Hope this helps

查看更多
萌系小妹纸
4楼-- · 2019-01-24 14:08

Kyle, after reading your comment to nemsev, I believe you want to disable your button, not your dialog function.

The binding...

<button data-bind="click: doAlert, enable: allowAlert">Open Dialog</button>
<div data-bind="click: doAlert">Click me for another call to trigger the dialog</div>
<button data-bind="click: toggleAllowAlert, text: allowButtonText"></button>

And the code...

var viewModel = function(){
    var self = this;
    self.allowAlert = ko.observable(true);
    self.allowButtonText = ko.computed(function(){
        if(self.allowAlert()){ 
            return 'Turn off button'; 
        } else { 
            return 'Turn on button'; 
        }
    });
    self.toggleAllowAlert = function(){
        self.allowAlert(!self.allowAlert());
    };
    self.doAlert = function(){
        alert('The dialog has opened');
    };
}

ko.applyBindings(new viewModel());

http://jsfiddle.net/DQg5P/1/

查看更多
beautiful°
5楼-- · 2019-01-24 14:18

You can use this approach that I did for anchors

http://jsfiddle.net/xCfQC/11/

(function() {
    //First make KO able to disable clicks on Anchors
    var orgClickInit = ko.bindingHandlers.click.init;
    ko.bindingHandlers.click.init = function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
      if(element.tagName === "DIV" && allBindingsAccessor().enable != null) {
          var disabled = ko.computed({
              read: function() {
                  return ko.utils.unwrapObservable(allBindingsAccessor().enable) === false;                                     
              }, 
              disposeWhenNodeIsRemoved: element
          });
          ko.applyBindingsToNode(element, { css: { disabled: disabled}  });
          var handler = valueAccessor(); 
          valueAccessor = function() {
              return function() {
                  if(ko.utils.unwrapObservable(allBindingsAccessor().enable)) { 
                      handler.apply(this, arguments);   
                  }
              }
          };         
      } 
      orgClickInit.apply(this, arguments);
    };
})();

More details: https://github.com/AndersMalmgren/Knockout.BindingConventions/wiki/Button-convention

查看更多
登录 后发表回答