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 以降、2 つのアクセントを使用^^して、親要素の「のみ」でディレクティブを検索できます。

Angular Docsrequireからの引用:

  • (no prefix)- 現在の要素で必要なコントローラーを見つけます。見つからない場合はエラーをスローします。
  • ?- 必要なコントローラを見つけようとするか、見つからない場合はリンク fn に null を渡します。
  • ^- 要素とその親を検索して、必要なコントローラーを見つけます。見つからない場合はエラーをスローします。
  • ^^- 要素の親を検索して、必要なコントローラーを見つけます。見つからない場合はエラーをスローします。
  • ?^- 要素とその親を検索して必要なコントローラーを見つけようとするか、見つからない場合はリンク fn に null を渡します。
  • ?^^- 要素の親を検索して必要なコントローラーを見つけようとするか、見つからない場合はリンク fn に null を渡します。

あなたの場合、に置き換え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');
}
...

これは、親ディレクティブのコントローラー、または 1 レベル上の親の親ディレクティブのコントローラーのいずれかを返します。直接の親のコントローラーを確実に取得する必要がある場合は、これを見つけました (より良い解決策があるかもしれませんが、私は知りません)知る):

...
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>

リンク関数が「ボックス a」で呼び出されると、parentCtrl はundefinedどちらの場合にも当てはまります。リンク関数が「ボックス b」で呼び出されると、parentCtrl はどちらの場合も「ボックス a」のコントローラーになります。

例 2:

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

リンク関数が「ボックス a」で呼び出されると、parentCtrl はundefinedどちらの場合にも当てはまります。リンク関数が「ボックス b」で呼び出されると、parentCtrl はどちらの場合も「ボックス a」のコントローラーのままですが、hasDirectBoxParent はfalseであるため、親と祖父母を区別できます。

于 2013-10-14T23:33:57.087 に答える