AngularJS directive only when the condition is true

前端 未结 3 1590
無奈伤痛
無奈伤痛 2021-01-06 21:50

I am going to have a contextmenu directive in ng-repeat items. Based on whether a condition is true, the directive should be applied. How do I put a condition like only when

相关标签:
3条回答
  • 2021-01-06 22:22

    Can you do something like this, using ng-if?

    <ul ng-controller="ListViewCtrl" >
       <li ng-repeat="item in items">
          <span>{{item.name}}</span>
          <div contextmenu ng-if="item.hasMenu"></div>
       </li>
    </ul>
    

    Here are the docs for ng-if.

    EDIT: If you are driving the context menu off of a class, you should be able to do this:

    <ul ng-controller="ListViewCtrl" >
       <li ng-class="{'hasmenu': item.hasMenu}" ng-repeat="item in items">{{item.name}} </li>
    </ul>
    
    0 讨论(0)
  • 2021-01-06 22:22

    I think this is pretty tricky if you don't want to change your DOM structure. If you could just place your contextmenu directive on a sub DOM node inside the <li> things would be a lot easier.

    However, let's assume you can't do that and let's also assume that you don't own the contextmenu directive so that you can't change it to your needs.

    Here is a possible solution to your problem that might be a bit hackish (actually I don't know!)

    'use strict';
    
    angular.module('myApp', [])
    
      .controller('TestController', ['$scope', function($scope) {
        $scope.items = [
            {name:1, hasMenu: true}, 
            {name:2, hasMenu: false }, 
            {name:3, hasMenu: true}
          ];
      }])
      .directive('contextmenu', function(){
        return {
          restrict: 'A',
          link: function(scope, element){
            element.css('color', 'red');
          }
        }
      })
      .directive('applyMenu', ['$compile', function($compile){
    
        return {
          restrict: 'A',
          link: function(scope, element){
            if (scope.item.hasMenu){
              //add the contextmenu directive to the element
              element.attr('contextmenu', '');
              //we need to remove this attr
              //otherwise we would get into an infinite loop
              element.removeAttr('apply-menu');
    
              //we also need to remove the ng-repeat to not let the ng-repeat 
              //directive come between us.
              //However as we don't know the side effects of 
              //completely removing it, we add it back after
              //the compile process is done.
              var ngRepeat = element.attr('ng-repeat');
              element.removeAttr('ng-repeat');
              var enhanced = $compile(element[0])(scope);
              element.html(enhanced);
              element.attr('ng-repeat', ngRepeat);
            }
          }
        }
      }]);
    

    I faked the contextmenu directive to just change the color to red just so that we can see it's taking place.

    Then I created an apply-menu attribute directive. This directive than checks if the hasMenu property is true and if so hooks in and adds the contextmenu directive and does a manual $compile process.

    However, what worries me a bit about this solution is that I had to temporally remove the ng-repeat directive (and also the apply-menu directive) to get the $compile process to act the way we want it to act. We then add the ng-repeat directive back once the $compile has been made. That is because we don't know the side effects of removing it entirely from the resulting html. This might be perfectly valid to do, but it feels a bit arkward to me.

    Here is the plunker: http://plnkr.co/edit/KrygjX

    0 讨论(0)
  • 2021-01-06 22:25

    You can do this way

    angularApp.directive('element', function($compile) {
            return {
                restrict: 'E',  
                replace: true,
                transclude: true,
                require: '?ngModel',
                scope: 'isolate',
                link: function($scope, elem, attr, ctrl) {
                    $scope.isTrue = function() {
                        return attr.hasMenu;
                    };
                  if($scope.isTrue())
                    //some html for control
                    elem.html('').show();
                  else
                    //some html for control
                    elem.html('').show(); 
    
                    $compile(elem.contents())($scope);
    
                }
            };
        });
    
    0 讨论(0)
提交回复
热议问题