在另一个指令的指令的隔离范围内调用函数

时间:2014-04-22 18:33:31

标签: angularjs

简单地说,我想从另一个指令访问指令的隔离范围。

$(element).scope()似乎返回父范围,而不是隔离范围。下面的描述有点罗嗦,所以这里是一个plunkr http://plnkr.co/edit/bG5JW5Ky0K3aTj8gTSsh?p=preview

下面的html显示我有一个keydown事件委托指令和另一个指令,它显示了我想要执行的代码,如果在突出显示该元素时按下“DOWN”箭头键。

<body ng-controller="MainCtrl">
<div id="page1" tabindex="-1" key-handler>
<a href="" id="testAnchor" class="highlight" on-down="API.setTarget('section0')">HIGHLIGHTED</a>
</div>
</body>

两个指令共享以下测试控制器

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

    // this API is injected as a service in the real code
    $scope.API = {};
    $scope.API.setTarget = function ( value ) {
    alert ( "$scope.API.setTarget " + value );
    return true;
  };                  
})

下面的“on-down”指令旨在可重用,并允许事件委托者执行“on-down”表达式中包含的功能。作为测试,我在链接函数中调用它来表明它符合我的期望。

.directive ( 'onDown', [ function (  ) {

return {

    restrict: 'A',
    scope: {
        'action': '&onDown'
    },

    link: function ( scope, element, attr ) {           
        // test call when the directive is created to show that it works
        scope.action ( );           
    }
}
}])

但是,当我尝试从另一个指令访问隔离范围以便我可以执行该代码时,会返回父范围。

.directive ( 'keyHandler', [

function ( ) {

    return {

              restrict: 'A',                    
              scope: {},

        link: function ( $scope, $element, $attr ) {

            $scope.$on('$destroy', function () {
                $element.unbind ( 'keydown' );
            });

            $element.bind ( 'keydown', function ( event ) {

                e = event || window.event;

                if ( e.stopPropagation ) e.stopPropagation ( );
                if ( e.preventDefault ) e.preventDefault ( );

                var target = e.target || e.srcElement;

                var keyCode = e.keyCode;

                // find all highlighted elements
                var highlightedEl = $('.highlight')[0];
                alert ( "highlightedEl " + $(highlightedEl).attr('id'));

                switch ( keyCode ) {

                case 40:
                  alert ( "down key pressed");
                              var downHandler = $(highlightedEl).attr('on-down');
                              if ( downHandler ) {
                                alert ( "found down handler");
                                  // trigger the function in the highlighted elements isolated scope
                                  // NOTE: targetScope seems to point to the controller scope rather than the highlighted elements isolated scope
                                  var targetScope = $(highlightedEl).scope();
                                  targetScope.action();
                              }
                  break;
                }
            });

          // give focus to this element so it receives all key events
          $scope.$evalAsync ( function ( ) {
            $element[0].focus();                        
          });               
        }
    }
}
]);

1 个答案:

答案 0 :(得分:0)

我知道解决此问题的最佳方法是使用控制器在指令之间共享信息。

您创建一个包含控制器的指令,该控制器具有可用于传递数据的方法。然后创建其他指令,使用Require:作为main指令,并在子指令中链接:连接并调用“父”指令中的方法......

app
  .directive('parentDirective', function(){
     return { 
              restrict: 'E', 
              replace: true,
              template: "<button ng-click='doSomething()'>Do something</button>",
              controller: function($scope) {
                   var somethingsToDo = ['something'];
                   $scope.doSomething = function() {
                          alert(somethingToDo.join());
                   }
                   this.addSomethingToDo = function(somethingToDo) {
                       somethingsToDo.push(somethingToDo);
                   }
             }
       };
  })
  .directive('nothingToDo', function() {
       return {
                restrict: 'A',
                require: 'parentDirective',
                link: function(scope, element, attrs, controller) {
                controller.addSomethingToDo('Nothing');
                }
              }
         }
  });