2014-04-22 93 views
0

簡而言之,我想從另一條指令訪問指令的隔離範圍。在另一條指令的指令的隔離範圍內調用函數

$(element).scope()似乎返回父作用域,而不是隔離作用域。下面的描述有點羅嗦,所以這裏是一個plunkr http://plnkr.co/edit/bG5JW5Ky0K3aTj8gTSsh?p=preview

下面的html顯示我有一個指令爲keydown事件委託和另一個指令,顯示我想要執行的代碼,如果按下「向下」箭頭鍵時該元素突出顯示。

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

「關於向下」指令下面旨在被重複使用,並且允許事件委託給執行包含在「在功能上下降「表達。作爲一個測試,我在鏈接函數中調用它來表明它符合我的期望。

.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();       
      });    
     } 
    } 
} 
]); 
+0

我剛剛發現了isolateScope ()似乎做我想要的。 – user2337247

回答

0

我知道解決此問題的最佳方式是使用控制器在指令之間共享信息。

您創建一個指令,其中包含一個控制器,該控制器有一個可用於傳入數據的方法。然後創建其他使用Require:for 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'); 
       } 
       } 
     } 
    }); 
+0

謝謝。這就是我正在做的事情。 scope.action()被映射到在控制器中設置的API.setTarget()。 調用element.isolateScope()而不是element.scope()似乎給了我正確的作用域,我需要在指令中調用scope.action(),該指令映射到父控制器中的API.setTarget()。 – user2337247