angularjs 指令:link 和控制器之间如何通信?

angularjs directive: how communicate between link and controller?

我有一个指令,我需要在指令控制器中访问其 'config' 属性值。 由于控制器构造函数首先被执行,从控制器到 link 的通信是可能的,但反之则不行。 实现这一目标的最佳方法应该是什么? 我考虑过以下方法

1)将变量添加到作用域- 在我看来,这会污染作用域,使变量在共享作用域的任何其他地方都可以访问。

2)使用$broadcast 还是和上面一样的问题

3) 在控制器的 this 上传递一个回调函数,并从 link 函数中以 config 作为参数调用它

4) 通过服务传递值- 在我的例子中,我有多个这样的指令需要通过该服务传递日期

或者是否有我错过的更好的方法?

module.directive('myDirective',function(){

return{
 restrict:'E',
 templateUrl:'path/to/html',
 link:function(scope,iElement,iAttrs,controller){

  var config=iAttrs.config;
//How to access this value inside the directive controller?

},
controller:function($scope){
//the directive attribute 'config' is required here for some larger computations which are not
//manipulating the DOM and hence should be seperated from the link function
})

在那里您可以使用独立作用域概念,在控制器中创建独立作用域并且不会从其父作用域原型继承。为此,您需要在指令选项中使用 scope: { ... } 。通过 attribute

在指令内传递作用域值有三种选择
  1. @ : 一种绑定方式
  2. = : 双向绑定
  3. & : 表达式

在您的情况下,前两种情况都可以,具体取决于您需要使用哪种情况。如果您只想将范围变量的值传递给指令,在这种情况下,您可以使用第一种方法,即 @ 单向绑定。

如果你想更新指令和控制器中的变量,即双向绑定,那么你需要使用 =

我认为 = 适合你的情况,所以你应该选择 =

标记

<my-directive config="config"></my-directive>

指令

app.directive('myDirective', function() {
  return {
    restrict: 'E',
    scope: {
      config: '='
    },
    templateUrl: 'path/to/abc.html',
    link: function(scope, iElement, iAttrs, controller) {
      //here it will be access as scope.config
      console.log(scope.config);
    },
    controller: function($scope) {
      console.log($scope.config); //here also it would be available inisde scope
      //you could put a watch to detect a changes on config
    }
  }
});

Demo Plunkr

更新

因为 config 值是从属性中提供的 {{}} 之类的表达式,所以我们可以通过将 [**$observe**][2] 放在 $attrs 上来在控制器内部获得这些更改。为此,您需要在控制器上注入 $attrs 依赖项,这将为您提供指令元素上可用的所有属性集合。在同一个 $attrs 对象上,我们将放置 $observe ,它与 $watch 的工作方式相同,后者进行脏检查,如果值发生变化,它会触发该手表。

指令

app.directive('myDirective', function() {
  return {
    restrict: 'E',
    templateUrl: 'path/to/abc.html',
    link: function(scope, iElement, iAttrs, controller) {
      //here it will be access as scope.config
      console.log(scope.config);
    },
    controller: function($scope,$attrs) {
      //you could put a watch to detect a changes on config
      $attrs.$observe('config', function(newV){
        console.log(newV);
      })
    }
  }
});

Updated Demo