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

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ようにディレクティブを偽造しました。colorred

次に、apply-menu属性ディレクティブを作成しました。このディレクティブは、プロパティが true かどうかをチェックし、hasMenutrue の場合はフックしてディレクティブを追加contextmenuし、手動$compileプロセスを実行します。

ただし、このソリューションについて少し心配しているのは、プロセスを希望どおりに動作させるために、ng-repeatディレクティブ (およびapply-menuディレクティブも)を一時的に削除する必要があったことです。ディレクティブが作成されたら、再度ディレクティブ$compileを追加します。これは、結果の html から完全に削除した場合の副作用がわからないためです。これは完全に有効かもしれませんが、私には少し面倒に感じます。ng-repeat$compile

ここにプランカーがあります: 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 に答える