1

我对 AngularJs 指令比较陌生,我试图了解范围是如何工作的。我想我理解得很好,但后来我遇到了如下问题。我的指令:

<ng-view>
    <div my-directive ng-click="foo()" >...</div>
</ng-view>

指令代码:

app.directive('myDirective',function(){
    return function(scope,element,attrs){
        scope.foo = function(){...}
    }
})

我希望foo()在单击元素时触发,但事实并非如此。用batarang检查范围我看到范围存在(id:#003),rootScope作为它的父级,但是当单击元素或其子级时,范围是根(id:#002),我还检查了angular.element($('div[my-directive]')).scope()它可能是一个batrang问题,但结果是一样的。

更新:我想我找到了问题的原因,在我的真实应用程序中,使用指令的元素位于指令内ngView,当我将指令放在 ngView 之外时,我在链接函数中定义的属性现在在范围内可见(根范围)。我猜这是由于异步加载,但我需要确认,在这个 fiffle中,我使用了带有静态模板的 ngView 但它不起作用(它起作用,我无法重现问题)。

4

2 回答 2

1

由于该指令没有指定新的范围(scope: true),或隔离范围(scope: { ... }),或使用嵌入,它将使用 HTML 中的“影响范围”。

如果您的指令在控制器外部使用,它将使用 $rootScope,foo并将在其上定义:

<div my-directive ng-click="foo()" >click me</div>
<div ng-controller="MainCtrl"></div>

在此处输入图像描述
fiddle

如果您的指令在控制器内部使用,它将使用该控制器的范围:

<div ng-controller="MainCtrl">
   <div my-directive ng-click="foo()" >click me</div>
</div>

在此处输入图像描述
fiddle

于 2013-06-21T18:07:54.247 回答
1

实现此目的的一种方法是在指令中使用模板和嵌入:

app.directive('myDirective', function () {
   return {
      template: '<div ng-click="foo()" ng-transclude></div>',
      transclude: true,
      controller: function ($scope, $element, $attrs) {
         $scope.foo = function () {...};
      }
   };
});

还有你的html:

<div my-directive>...<div>

这样做的原因是您在指令的范围foo定义函数。在您最初的尝试中,预计将在父范围内。虽然您的指令可以更改父作用域的定义,但这不太可能是您想要的。您实际上是在要求您的指令用户了解指令的内部定义功能。这有点尴尬/倒退。foofoofoo

于 2013-06-21T17:26:33.503 回答