如何在指令中可靠地获得控制器范围?

时间:2014-01-22 05:22:22

标签: angularjs scope angularjs-directive angularjs-controller

假设我有一个指令,只是打印出其范围ID

.directive('myCustomer', function() {
  return {
    template: 'directive scope {{$id}}',
    link: function(scope, el, attrs) {
      //console.log('controller scope', 'HOW?');
    }
  };
});

案例1:
像往常一样在控制器中使用它。 它为控制器和指令打印出003。

<div ng-controller="Ctrl">
  controller scope : {{$id}}
  <div my-customer></div>
</div>

演示:http://plnkr.co/edit/3UyDwk?p=preview

案例2:
接下来,我在控制器中使用了相同的指令,如ng-include和ng-repeat中的以下内容。 以下打印出范围ID,003,004,005 ......等等。

<div ng-controller="Ctrl">
  controller scope : {{$id}}
  <div ng-include="'ng-repeat.html'"></div>
</div>

演示:http://plnkr.co/edit/6vMpCt?p=preview

我理解ng-include和ng-repeat创建自己的范围。

问题:
我的问题是“如何在指令中可靠地获得控制器范围?”

从上面的案例1和案例2中,我想在指令中使用相同的代码获取范围“003”。

我可以将scope用于案例1,
但对于案例2,我需要使用scope.$parent.$parent
如果我只使用ng-repeat,我需要使用scope.$parent
如果我在ng-include和ng-include中使用它会怎么样? scope.$parent.$parent.$parent…

我正在搜索不存在的scope.controllerScope()代码。

我的用例是在不使用隔离范围的情况下从指令调用控制器中的函数。

希望我的问题很明确。

1 个答案:

答案 0 :(得分:1)

我尝试了一些技巧,但这是我找到的最佳解决方案:

这是一个掠夺者:http://plnkr.co/edit/bA6jww?p=preview

我们可以通过修饰$ controllerProvider来改变所有控制器:

app.config(function($provide){
  $provide.decorator('$controller', ['$delegate', function($delegate) {
    return function (expression, locals) {
      if (expression != angular.noop) {
        locals.$scope.$controllerId = locals.$scope.$id;
      }
      return $delegate(expression,locals)
    }
  }]); 
})

现在我们可以通过原型链对其进行数据绑定:

{{$controllerId}}

有一点需要注意,隔离的范围不能继承此值,但我想这是一种想要的行为,因为这些范围无论如何都不会从外部控制器继承。