使用AngularJS启用/禁用锚点标记

时间:2014-05-02 09:50:48

标签: angularjs angularjs-directive

如何使用指令方法启用/禁用锚标记?

示例:

  1. 点击编辑链接时,创建&删除需要被禁用或变灰
  2. 点击创建链接,编辑&删除需要被禁用或变灰
  3. JAVASCRIPT:

        angular.module('ngApp', []).controller('ngCtrl',['$scope', function($scope){
    
        $scope.create = function(){
          console.log("inside create");
        };
    
        $scope.edit = function(){
          console.log("inside edit");
        };
    
        $scope.delete = function(){
        console.log("inside delete");
        };
    
        }]).directive('a', function() {
           return {
                restrict: 'E',
                link: function(scope, elem, attrs) {
                    if(attrs.ngClick || attrs.href === '' || attrs.href === '#'){
                        elem.on('click', function(e){
                            e.preventDefault();
                            if(attrs.ngClick){
                                scope.$eval(attrs.ngClick);
                            }
                        });
                    }
                }
           };
        }); 
    

    LINK to CODE

10 个答案:

答案 0 :(得分:55)

<强>更新 禁用href在链接函数返回中更好。以下代码已更新。

aDisabled自然在ngClick之前执行,因为指令按字母顺序排序。将aDisabled重命名为tagDisabled时,该指令会工作。


To&#34;禁用&#34; &#34; a&#34;标签,我想要以下内容:

  1. href点击后无法关注的链接
  2. ngClick点击时不会触发的事件
  3. 通过添加disabled
  4. 更改了样式

    该指令通过模仿ngDisabled指令来完成此操作。基于a-disabled指令的值,所有上述功能都被切换。

    myApp.directive('aDisabled', function() {
        return {
            compile: function(tElement, tAttrs, transclude) {
                //Disable ngClick
                tAttrs["ngClick"] = "!("+tAttrs["aDisabled"]+") && ("+tAttrs["ngClick"]+")";
    
                //return a link function
                return function (scope, iElement, iAttrs) {
    
                    //Toggle "disabled" to class when aDisabled becomes true
                    scope.$watch(iAttrs["aDisabled"], function(newValue) {
                        if (newValue !== undefined) {
                            iElement.toggleClass("disabled", newValue);
                        }
                    });
    
                    //Disable href on click
                    iElement.on("click", function(e) {
                        if (scope.$eval(iAttrs["aDisabled"])) {
                            e.preventDefault();
                        }
                    });
                };
            }
        };
    });
    

    这是一种可能表示禁用标记的css样式:

    a.disabled {
        color: #AAAAAA;
        cursor: default;
        pointer-events: none;
        text-decoration: none;
    }
    

    And here is the code in action, with your example

答案 1 :(得分:23)

我的问题略有不同:我有定义href的锚标签,我想使用ng-disabled来防止链接在点击时转到任何地方。解决方案是在禁用链接时取消设置href,如下所示:

<a ng-href="{{isDisabled ? '' : '#/foo'}}"
   ng-disabled="isDisabled">Foo</a>

在这种情况下,ng-disabled仅用于为元素设置样式。

如果你想避免using unofficial attributes,你需要自己设计样式:

<style>
a.disabled {
    color: #888;
}
</style>
<a ng-href="{{isDisabled ? '' : '#/foo'}}"
   ng-class="{disabled: isDisabled}">Foo</a>

答案 2 :(得分:9)

对于不想要复杂答案的人,我使用Ng-If来解决类似问题:

<div style="text-align: center;">
 <a ng-if="ctrl.something != null" href="#" ng-click="ctrl.anchorClicked();">I'm An Anchor</a>
 <span ng-if="ctrl.something == null">I'm just text</span>
</div>

答案 3 :(得分:6)

修改@ Nitin answer以使用动态停用:

angular.module('myApp').directive('a', function() {
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {
      elem.on('click', function(e) {
        if (attrs.disabled) {
          e.preventDefault(); // prevent link click
        }
      });
    }
  };
});

每次点击都会检查是否存在disabled属性及其值。

答案 4 :(得分:4)

<强>声明:

OP对另一个答案发表了评论:

  

我们可以为按钮或输入标签设置ngDisabled;通过使用CSS,我们可以   使按钮看起来像锚标签,但这并没有多大帮助!一世   我更热衷于研究如何使用指令方法来完成它   或角度方式吗?


您可以使用控制器范围内的变量根据您点击的最后一个按钮/链接禁用链接/按钮,方法是使用ng-click将变量设置为正确的值和ng-disabled根据变量中的值在需要时禁用按钮。

我已更新您的Plunker以便给您一个想法。

但基本上,它是这样的:

 <div>
       <button ng-click="create()" ng-disabled="state === 'edit'">CREATE</button><br/>
       <button ng-click="edit()" ng-disabled="state === 'create'">EDIT</button><br/>
       <button href="" ng-click="delete()" ng-disabled="state === 'create' || state === 'edit'">DELETE</button>
    </div>

答案 5 :(得分:3)

您是否尝试过对disabled || someAction()等表达式进行延迟评估?

让我们假设我在我的控制器中定义了类似的内容:

$scope.disabled = true;

然后我可以禁用链接并应用内联样式,如下所示:

<a data-ng-click="disabled || (GoTo('#/employer/'))" data-ng-style="disabled && { 'background-color': 'rgba(99, 99, 99, 0.5)', }">Higher Level</a>

或者更好的是仍然禁用链接并应用类似的类:

<a data-ng-click="disabled || (GoTo('#/employer/'))" data-ng-class="{ disabled: disabled }">Higher Level</a>

注意:您将通过该语句将class="disabled"应用于DOM元素。

在此阶段,您只需处理您的行动GoTo()即可。在我的情况下,它就像重定向到关联状态一样简单:

$scope.GoTo = function (state) {
    if (state != undefined && state.length > 0) {
        $window.location.hash = state;
    }
};

不受ngDisabled的限制,而是受到您决定做的事情的限制。

通过这种技术,我成功应用了权限级别检查,以启用或禁用用户访问模块的某些部分。

Simple plunker to demonstrate the point

答案 6 :(得分:1)

您可以创建一个与ng-disabled类似的自定义指令,并通过以下方式禁用一组特定的元素:

  1. 观看自定义指令的属性更改,例如my-disabled
  2. 克隆当前元素而不添加事件处理程序。
  3. 将css属性添加到克隆元素和其他属性或事件处理程序 提供元素的禁用状态。
  4. 在监视属性上检测到更改时,将当前元素替换为克隆元素。
  5. <强> HTML

       <a my-disabled="disableCreate" href="#" ng-click="disableEdit = true">CREATE</a><br/>
       <a my-disabled="disableEdit" href="#" ng-click="disableCreate = true">EDIT</a><br/>
       <a my-disabled="disableCreate || disableEdit" href="#">DELETE</a><br/>
       <a href="#" ng-click="disableEdit = false; disableCreate = false;">RESET</a>
    

    <强> JAVASCRIPT

    directive('myDisabled', function() {
      return {
    
        link: function(scope, elem, attr) {
          var color = elem.css('color'),
              textDecoration = elem.css('text-decoration'),
              cursor = elem.css('cursor'),
              // double negation for non-boolean attributes e.g. undefined
              currentValue = !!scope.$eval(attr.myDisabled),
    
              current = elem[0],
              next = elem[0].cloneNode(true);
    
          var nextElem = angular.element(next);
    
          nextElem.on('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
          });
    
          nextElem.css('color', 'gray');
          nextElem.css('text-decoration', 'line-through');
          nextElem.css('cursor', 'not-allowed');
          nextElem.attr('tabindex', -1);
    
          scope.$watch(attr.myDisabled, function(value) {
            // double negation for non-boolean attributes e.g. undefined
            value = !!value;
    
            if(currentValue != value) {
              currentValue = value;
              current.parentNode.replaceChild(next, current);
              var temp = current;
              current = next;
              next = temp;
            }
    
          })
        }
      }
    });
    

答案 7 :(得分:1)

您可以使用angular指令重新定义a标记:

angular.module('myApp').directive('a', function() {
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {
      if ('disabled' in attrs) {
        elem.on('click', function(e) {
          e.preventDefault(); // prevent link click
        });
      }
    }
  };
});

在html中:

<a href="nextPage" disabled>Next</a>

答案 8 :(得分:0)

期望锚标记通向带有网址的静态页面。我认为按钮更适合您的用例,然后您可以使用ng禁用它来禁用它。来自文档:https://docs.angularjs.org/api/ng/directive/ngDisabled

答案 9 :(得分:0)

ui-router v1.0.18引入了对锚标签上的ng-disabled的支持

示例:<a ui-sref="go" ng-disabled="true">nogo</a>