【问题标题】:AngularJS directive only when the condition is trueAngularJS 指令仅在条件为真时
【发布时间】:2013-08-25 07:04:56
【问题描述】:

我将在 ng-repeat 项目中添加一个 contextmenu 指令。 根据条件是否为真,应应用该指令。 如何设置仅当 item.hasMenu == true 然后应用指令时的条件?

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

编辑

这似乎对我有用。首先是指令。

app.directive('menu',function(){

    return {
        restrict : 'A',

        link : function(scope,element,attrs){

            if(scope.hasMenu){
                        element.contextmenu({
                                        menu:[
                                        {title:"Remove" , "cmd" : "remove"},
                                        {title:"Add" , "cmd" : "add"},
                                        ],
                                        select:function(event,ui){
                                            //alert("select " + ui.cmd + " on" + ui.target.text());
                                            if (ui.cmd ==='remove'){
                                                alert('Remove selected on ' + scope.item);
                                            }
                                            if (ui.cmd ==='add'){
                                                alert("Add selected");
                                            }
                                        }
                        });
            }

        }
    }
    }
);

然后是html

 <ul ng-controller="ListViewCtrl" >
<li menu  ng-repeat="item in items">{{item.name}} </li>
</ul>

【问题讨论】:

  • 你能显示上下文菜单指令模板吗?您在哪里添加上下文菜单的标记?
  • 我正在尝试使用 github.com/mar10/jquery-ui-contextmenu 作为指令。到目前为止,我还没有创建指令。这个特定的插件具有基于类过滤元素的委托功能。我正在考虑将其用作过滤条件,但不确定是否可行。
  • 在这种情况下你应该可以使用ng-class="{'hasmenu': item.hasMenu}

标签: angularjs angularjs-directive


【解决方案1】:

你能用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.

编辑: 如果您将上下文菜单从课程中移开,您应该可以这样做:

<ul ng-controller="ListViewCtrl" >
   <li ng-class="{'hasmenu': item.hasMenu}" ng-repeat="item in items">{{item.name}} </li>
</ul>

【讨论】:

    【解决方案2】:

    你可以这样做

    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);
    
                }
            };
        });
    

    【讨论】:

      【解决方案3】:

      如果您不想更改 DOM 结构,我认为这非常棘手。如果您可以将 contextmenu 指令放在 &lt;li&gt; 内的子 DOM 节点上,事情会容易得多。

      但是,假设您不能这样做,并且还假设您不拥有 contextmenu 指令,因此您无法根据需要对其进行更改。

      这是解决您的问题的可能方法,可能有点骇人听闻(实际上我不知道!)

      '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);
              }
            }
          }
        }]);
      

      我伪造了contextmenu 指令,只是将color 更改为red,以便我们可以看到它正在发生。

      然后我创建了一个apply-menu 属性指令。该指令然后检查hasMenu 属性是否为真,如果是,则挂钩并添加contextmenu 指令并执行手动$compile 过程。

      但是,我对此解决方案有点担心的是,我必须暂时删除 ng-repeat 指令(以及 apply-menu 指令)以使 $compile 进程按照我们希望的方式运行.然后,一旦创建了 $compile,我们就会添加 ng-repeat 指令。那是因为我们不知道从生成的 html 中完全删除它的副作用。这可能是完全有效的,但对我来说感觉有点尴尬。

      这里是 plunker:http://plnkr.co/edit/KrygjX

      【讨论】:

      • 嗨@Christoph。我将 applyMenu 指令中的 if 条件直接添加到 contextmenu 指令中。我没有看到任何副作用。是的,删除 ng-repeat 很尴尬
      • 所以您更改了您不拥有的指令中的代码?这会导致维护噩梦!
      • 不,我没有更改指令代码。我刚刚添加了一个条件来确定元素是否有contextmenu
      猜你喜欢
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      相关资源
      最近更新 更多