2

我将在 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>
4

3 回答 3

6

你可以做这样的事情,使用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>

这是 ng-if 的文档。

编辑:如果您将上下文菜单从课程中移开,您应该能够做到这一点:

<ul ng-controller="ListViewCtrl" >
   <li ng-class="{'hasmenu': item.hasMenu}" ng-repeat="item in items">{{item.name}} </li>
</ul>
于 2013-08-22T13:55:48.800 回答
1

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

但是,让我们假设您不能这样做,并且我们还假设您不拥有该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指令只是将 更改colorredjust 以便我们可以看到它正在发生。

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

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

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

于 2013-08-22T15:12:20.930 回答
0

你可以这样做

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

            }
        };
    });
于 2013-08-22T14:25:49.333 回答