Disable anchor tag in knockout.js

2019-04-18 15:01发布

I need to disable the anchor tag inside a foreach loop of knockout.js in HTML.

Here is my code:

<a id="aQStreamSkype" data-bind="attr:{href: ''}, click: $parent.StoreUserClick,disable: ($data.SkypeId == 'null')">Skype </a>

8条回答
forever°为你锁心
2楼-- · 2019-04-18 15:24

With some override magic you can get this behaviour without that your view or ViewModel code need changes

  (function () {
      var orgClickInit = ko.bindingHandlers.click.init;
      ko.bindingHandlers.click.init = function (element, valueAccessor, allBindingsAccessor, viewModel) {
          if (element.tagName === "A" && allBindingsAccessor().enable != null) {
              var disabled = ko.computed(function () {
                  return ko.utils.unwrapObservable(allBindingsAccessor().enable) === false;
              });
              ko.applyBindingsToNode(element, { css: { disabled: disabled} });
              var handler = valueAccessor();
              valueAccessor = function () {
                  return function () {
                      if (ko.utils.unwrapObservable(allBindingsAccessor().enable)) {
                          handler.apply(this, arguments);
                      }
                  }
              };

          }
          orgClickInit(element, valueAccessor, allBindingsAccessor, viewModel);
      };
  })();

When you include that code the enable binding will work for anhors

Fiddle, it uses my convention library so ignore that part http://jsfiddle.net/xCfQC/4/

查看更多
别忘想泡老子
3楼-- · 2019-04-18 15:27

I found ko.plus an excellent library which implements command pattern. The 'action' can not be executed until 'canExecute' condition is true.

var vm = {
    enabled: ko.observable(false),
    StoreUserClick: ko.command({
        action: function () {
            window.alert('Command is active')
        },
        canExecute: function () {
            return vm.enabled();
        }
    })
}
ko.applyBindings(vm);
a.disabled {
    color: gray;
    text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://raw.githubusercontent.com/stevegreatrex/ko.plus/master/dist/ko.plus.js"></script>

<a href="" id="aQStreamSkype" data-bind="click: StoreUserClick, css: { disabled: !StoreUserClick.canExecute() }">Skype</a>
<br />
<br />
<input type="checkbox" data-bind="checked: enabled">enabled

查看更多
可以哭但决不认输i
4楼-- · 2019-04-18 15:35

Disable only works with form elements, not anchor tags. You could use the visible binding instead, and just hide the link if there is no user id. If you do want to show something even if there isn't a user id, then add a span with the opposite visible test, then one will be shown if there is a user id, and the other if there isn't:

<a id="aQStreamSkype" data-bind="attr:{href: ''}, click: $parent.StoreUserClick, visible: ($data.SkypeId !== 'null')">Skype </a>
<span class="notLink" data-bind="visible: ($data.SkypeId === 'null')">Skype </span>

As a side note, if SkypeId is an observable, you will need to call it as one in your comparison check:

($data.SkypeId() !== 'null')
查看更多
SAY GOODBYE
5楼-- · 2019-04-18 15:42

Anchor tags cannot be disabled.
The easiest is to use ko if binding and then render a span instead of the anchor if the skype id is null

<!-- ko if: skypeId === null -->
    <span >No Skype Id</span>
<!-- /ko -->
<!-- ko if: skypeId !== null -->
    <a id="aQStreamSkype" data-bind="attr:{href: ''}, click: $parent.StoreUserClick,text: skypeId"></a>
<!-- /ko -->

Here is a fiddle

查看更多
Bombasti
6楼-- · 2019-04-18 15:44

If there is no href attribute on a element but only an action in a click binding, then an easy way would be passing expression condition && handler to a click binding.

If condition is observable you'll need to add parentheses.

<a data-bind="click: flag1() && handler">Enabled link</a>
<a data-bind="click: flag2() && handler">Disabled link</a>

It will be evaluated as false if condition is false (so nothing will happen),
and will be evaluated as a handler if condition is true.

Fiddle here

查看更多
欢心
7楼-- · 2019-04-18 15:45

Knockout enable/disable binding do not support anchor tags.

So you have 2 solution to this.

Solution 1

<a href='#' title="Skype" data-bind='click: function() { 
 if(($data.SkypeId !== 'null'))
 {
    //call the desired method from here
 }' >

Solution 2

This button displays only when your condition is success and it has click binding

<a data-bind="click: $parent.StoreUserClick, visible: ($data.SkypeId != 'null')" href="#" title="Skype">

This button displays only when your negative condition is success and it do not have click binding

<a data-bind="visible: ($data.SkypeId == 'null')" href="#" title="Skype ">
查看更多
登录 后发表回答