20

我正在尝试以递归方式到达父“框”指令的控制器:

<body ng-app="main">

<!-- no nesting: parent is the just body -->
<box></box>

<script type="text/javascript">
angular.module('main', [])
.directive('box', function() {
    return {
        restrict: 'E',
        controller: function() { },
        require: '?^box',  // find optional PARENT "box" directive
        link: function(scope, iElement, iAttrs, controller) {
            // controller should be undefined, as there is no parent box
            alert('Controller found: ' + (controller !== undefined));
        }
    };
});
</script>
</body>

我希望控制器变量undefined在链接函数中,但我得到了实际盒子指令的控制器。

所以我的问题是......在这种情况下如何访问 PARENT 控制器:

<box>
    <box></box>
</box>

http://jsfiddle.net/gjv9g/1/

4

3 回答 3

39

从 Angular 1.3 开始,您可以使用两个重音符号^^“仅”在父元素中搜索指令。

引用来自Angular Docs 的内容require

  • (no prefix)- 在当前元素上找到所需的控制器。如果找不到则抛出错误。
  • ?- 尝试定位所需的控制器,如果未找到,则将 null 传递给链接 fn。
  • ^- 通过搜索元素及其父元素找到所需的控制器。如果找不到则抛出错误。
  • ^^- 通过搜索元素的父元素找到所需的控制器。如果找不到则抛出错误。
  • ?^- 尝试通过搜索元素及其父元素来定位所需的控制器,如果未找到,则将 null 传递给链接 fn。
  • ?^^- 尝试通过搜索元素的父元素来定位所需的控制器,如果未找到,则将 null 传递给链接 fn。

在您的情况下,替换require: '?^box',require: '?^^box',

于 2015-02-16T16:12:56.947 回答
18

好的,找到了...

如果您想获取父元素的控制器:

...
link: function(scope, iElement, iAttrs, controller) {
    // http://docs.angularjs.org/api/angular.element
    // jQuery/jqLite Extras:
    //
    // controller(name) - retrieves the controller of the current element or its parent.
    // By default retrieves controller associated with the ngController directive.
    // If name is provided as camelCase directive name, then the controller for this
    // directive will be retrieved (e.g. 'ngModel').
    var parentCtrl = iElement.parent().controller('box');
}
...

这将返回父指令的控制器,或者更高一级的父指令的控制器,如果您需要确保获得 DIRECT 父指令的控制器,我发现了这个(也许有更好的解决方案,我没有知道):

...
controller: function($scope, $element) {
    // store the element in controller, we'll need it later
    this.$element = $element;
},
// works in both pre and post link functions
link: function() {
    var parentElement = $element.parent();
    var parentCtrl = parentElement.controller('box');

    var hasDirectBoxParent = parentCtrl && parentCtrl.$element[0] === parentElement[0];

}
...

示例 1:

<box id="a">
    <box id="b"></box>
<box>

当在“box a”上调用链接函数时,parentCtrlundefined在这两种情况下都是。当在“box b”上调用链接函数时,parentCtrl 在这两种情况下都是“box a”的控制器。

示例 2:

<box id="a">
    <div>
        <box id="b"></box>
    </div>
<box>

当在“box a”上调用链接函数时,parentCtrlundefined在这两种情况下都是。当在“box b”上调用链接函数时,在这两种情况下 parentCtrl 仍然是“box a”的控制器,但 hasDirectBoxParent 是false,因此您可以区分父级和祖级。

于 2013-10-14T23:33:57.087 回答
4

require将控制器从所需(父)指令注入到当前指令(来自角度文档:“需要 - 需要另一个指令并将其控制器作为链接函数的第四个参数注入” http://docs.angularjs.org/指南/指令

所以也许你已经得到了你想要的?也就是说,父控制器通过您的controller参数注入到子控制器中。

于 2013-10-13T00:51:22.730 回答