Angular指令转换创建新范围?

时间:2013-12-07 16:01:21

标签: angularjs angularjs-directive angularjs-scope

我正在尝试为模态窗口创建指令组件,它关注模态行为,例如打开,关闭,处理zIndex等。

模态组件的内容由Controller控制。 到目前为止,想法很好,但是当我试图拥有

<modal ng-controller="MyController">
  Some content which will be transcluded with dynamic {{value}} from MyController
</modal>

失败并且不呈现{{value}} 我必须将模态包装到控制器

<div ng-controller="MyController">
  <modal>
    Some content which will be transcluded with dynamic {{value}} from MyController
  </modal>
</div>

有没有办法,如何让第一个例子有效,或者这是不可能的,为什么角度这样做呢?

最后有一个关于plunker的完整例子。

var app = angular.module('plunker', []);
app.directive("modal", function() {
  return {
    restrict:'E',
    replace:true,
    transclude:true,
    scope: false,
    template:'<div class="modal">Modal scope {{$id}}<div ng-transclude></div></div>',
    link: function($scope) {
      console.log("directive scope ", $scope.$id)
    }
  }  
})

app.controller('DetailControl', function($scope, $location) {
  console.log("controller scope ", $scope.$id)
  $scope.name = 'World';
});

和这个HTML

<body>
main scope {{$id}}

Controller on same element as modal<br>

<modal ng-controller="DetailControl">
  <div>
    content scope (transclude) {{$id}}<br>
    Some content of modal window. The name is {{name || '-unknown-'}}
  </div>
</modal>

Controller outside modal
<div ng-controller="DetailControl">
  Controller scope {{$id}}
  <modal>
    <div>
      content scope (transclude) {{$id}}<br>
      Some content of modal window. The name is {{name || '-unknown-'}}
    </div>
  </modal>
</div>
<body>

这里是plunker http://plnkr.co/edit/WOgZKB3e0bQUASMhFVOp?p=preview

2 个答案:

答案 0 :(得分:2)

尝试使用传递范围的transclude: http://docs.angularjs.org/api/ng.$compile

transcludeFn - &gt;范围

“transcludeFn - 转换链接函数预先绑定到正确的转换范围。范围可以被可选的第一个参数覆盖。这与指令控制器的$ transclude参数相同.function([scope],cloneLinkingFn )“。

答案 1 :(得分:2)

问题是ngController指令创建了自己的范围。执行<modal ng-controller="MyController">时,ngController范围是modal的兄弟,因此modal无法在该控制器中看到(在某种意义上是横向)。

ngController是父项时,它有效,因为您正在使用scope: false,这会导致您的指令从其父项继承它的范围。

您可以将控制器附加到指令,而不是使用单独的ngController指令:

  app.directive("modal", function() {
    return {
      controller: function($scope, $location) {
        console.log("controller scope ", $scope.$id)
        $scope.name = 'World';
     }
  }  

这种方法将为您的指令提供良好的封装,因为它不再依赖于外部控制器 - 这很好。一个优点是您不再需要协调多个范围。

如果需要多个指令进行通信,可以使用require允许多个指令共享对一个父指令控制器的访问权限。这是Angular内部采用的方法(例如在'ng-switch`