简体   繁体   English

在knockout.js中禁用锚标记

[英]Disable anchor tag in knockout.js

I need to disable the anchor tag inside a foreach loop of knockout.js in HTML. 我需要在HTML中的knockout.js的foreach循环中禁用锚标记。

Here is my code: 这是我的代码:

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

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 binding使用ko if binding skype id为null,则使用span而不是anchor

<!-- 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 这是一个小提琴

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. 如果没有href的属性, a一个元素,但只有一个动作click binding ,那么一个简单的方法将被路过的表达condition && handler ,以点击绑定。

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), 如果条件为false ,它将被评估为false (因此不会发生任何事情),
and will be evaluated as a handler if condition is true . 如果condition为true ,将被评估为处理程序。

Fiddle here 在这里小提琴

First off, there's a school of thought with which I have some sympathy that says just don't do it . 首先,有一种思想流派,我有一些同情,说不要这样做 A hyperlink that does nothing is just text. 没有任何作用的超链接只是文本。

However, I can see the flip side of the coin - I came across this same problem because I am using a Bootstrap dropdown menu which contains anchor tags as menu options, and to my mind it gives a better user experience to show the menu options as disabled rather than just not show them at all, and I feel it's cleaner to 'disable' the hyperlink than to include markup for a hyperlink and a span with the same text and then conditionally show one or the other. 然而,我可以看到硬币的另一面 - 我遇到了同样的问题,因为我使用Bootstrap下拉菜单,其中包含锚标签作为菜单选项,在我看来,它提供了更好的用户体验,以显示菜单选项禁用而不是根本不显示它们,我觉得“禁用”超链接比包含超链接的标记和具有相同文本的span更清晰,然后有条件地显示其中一个。 So, my solution was: 所以,我的解决方案是:

<a data-bind="click: checkCondition() ? myFunction : null, css: { disabled: !checkCondition() }"></a>

Note that checkCondition() is a function which returns true or false, indcating whether the hyperlink should be enabled or not. 请注意, checkCondition()是一个返回true或false的函数,指示是否应启用超链接。 The css binding is just styling the hyperlink to appear disabled - you may have to add your own .disabled CSS class if you're not using Bootstrap. css绑定只是将超链接设置为禁用样式 - 如果您不使用Bootstrap,则可能必须添加自己的.disabled CSS类。

The key to this working is that the anchor has no href attribute, so it's useless as a hyperlink without the Knockout click binding, which means that you could just as easily use this method with any element type (eg this could be a clickable span as easily as an anchor). 这个工作的关键是锚没有href属性,所以它没有Knockout click绑定作为超链接是无用的,这意味着您可以轻松地将此方法与任何元素类型一起使用(例如,这可以是可点击的span如很容易作为一个锚)。 However, I wanted to use an anchor so that my styling continued to be applied without any extra work. 但是,我想使用一个锚点,这样我的造型就可以继续使用,而无需任何额外的工作。

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. 您可以使用可见绑定,只是在没有用户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: 如果你确实想要显示一些东西,即使没有用户ID,那么添加一个带有相反可见测试的跨度,如果有用户ID,则会显示一个,如果没有,则显示另一个:

<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: 作为旁注,如果SkypeId是可观察的,您需要在比较检查中将其称为一个:

($data.SkypeId() !== 'null')

With some override magic you can get this behaviour without that your view or ViewModel code need changes 使用一些覆盖魔法,您可以获得此行为,而不需要您的视图或ViewModel代码需要更改

  (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 当您包含该代码时,启用绑定将适用于anhors

Fiddle, it uses my convention library so ignore that part http://jsfiddle.net/xCfQC/4/ 小提琴,它使用我的约定库,所以忽略那部分http://jsfiddle.net/xCfQC/4/

Knockout enable/disable binding do not support anchor tags . Knockout启用/禁用绑定不支持锚标记

So you have 2 solution to this. 所以你有2个解决方案。

Solution 1 解决方案1

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

Solution 2 解决方案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 ">

I found ko.plus an excellent library which implements command pattern. 我发现ko.plus是一个实现命令模式的优秀库。 The 'action' can not be executed until 'canExecute' condition is true. 在'canExecute'条件为真之前,不能执行'action'。

 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 

我喜欢使用的另一个选项是使用“css”指令禁用锚点:

<a id="aQStreamSkype" data-bind="css: { disabled: $data.SkypeId == 'null' }">Skype</a>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM