试图访问同一指令的父控制器

时间:2015-11-17 18:26:38

标签: angularjs angularjs-directive

我无法单独从嵌套的控制器访问父指令的控制器。但是,当ngIf与嵌套指令一起使用时,访问父控制器会起作用。我想知道ngIf引入了什么变化,以便能够在没有它的情况下访问父控制器。

指令如下所示:

angular.module("myApp", [])
.directive("some", function() {
  return {
    restrict: 'A',
    require: ['?^some', '?^^some'],
    link: function(scope, element, attrs, parentCtrls) {
      attrs.$observe("some", function(someValue) {
        scope.someName = someValue;
        scope.parentCtrls = parentCtrls
        console.log(someValue + " ctrls: " + parentCtrls);
      });
    },
    controller: function($scope) {
      this.toString = function() { return $scope.someName }
    }
  }
});

和嵌套元素可以任意深度的代码:

<html ng-app="myApp">
  <head><!-- proper init here --></head>

  <body>
    <div some="outer">
      outer parent ctrls: {{parentCtrls.toString()}}
      <div>
        <div some="nested1">nested1 parent ctrls: {{parentCtrls.toString()}}</div>
        <div some="nested2" ng-if="true">nested2 parent ctrls: {{parentCtrls.toString()}}</div>
      </div>
    </div>
  </body>
</html>

效果是?^somoe始终解析为自我控制器(例如here解释)和?^^some仅针对nested2解析为父控制器。 可以在plunker上检查(在角度1.3.15和1.4.7上测试)。注意:由于范围,上面的例子实际上是错误的(我会尽快更新示例)由outernested1分享。在一些更复杂的情况下仍存在问题,并且接受的答案正确截获了它。

修改

接受的答案足以让我找到理想的方式。 Angular通过调用element.parent().inheritedData('$' + name + 'Controller')来查找父指令的控制器。因此,我可以使用?^^some代替element.parent().inheritedData('$someController')来访问所需的父控制器。

1 个答案:

答案 0 :(得分:1)

如果angular必须使用嵌套指令编译html,它将分三个阶段进行:

  1. 从外部编译到内部指令
  2. 从外部指令到内部指令的预链接
  3. 从内部指令到外部指令的后链接(即链接阶段)。
  4. 在后链接阶段,范围与指令绑定。这意味着&#34;嵌套1&#34;和&#34;嵌套2&#34;在&#34;外部&#34;之前,它们的范围是有约束力的。受其范围约束。

    如果现在使用ng-if,这会对此子树的编译产生终止影响,并且范围的绑定会延迟,直到表达式在后续编译周期中被验证为真实。在这种情况下,&#34;嵌套2&#34;在&#34;外部&#34;之后是它的范围。受到约束。