親の「ボックス」ディレクティブのコントローラーに再帰的に到達しようとしています:
<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
であると想定していますが、実際のボックスディレクティブのコントローラーを取得しています。
だから私の質問は...このような場合に親コントローラーにアクセスする方法です:
<box>
<box></box>
</box>
OK、見つけた...
親要素のコントローラーを取得したい場合:
...
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レベル上の親の親ディレクティブのコントローラーのいずれかを返します。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>
「ボックス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
なので、親を祖父母から区別できます。
Angular 1.3なので、2つのアクセントを使用できます^^
は、親要素「のみ」でディレクティブを検索します。
require
のAngular Docsからの引用:
(no prefix)
-現在の要素で必要なコントローラーを見つけます。見つからない場合はエラーをスローします。?
-必要なコントローラーを見つけるか、見つからない場合はリンクfnにnullを渡そうとします。^
-要素とその親を検索して、必要なコントローラーを見つけます。見つからない場合はエラーをスローします。^^
-要素の親を検索して、必要なコントローラーを見つけます。見つからない場合はエラーをスローします。?^
-要素とその親を検索して必要なコントローラーを見つけようとします。見つからない場合は、リンクfnにnullを渡します。?^^
-要素の親を検索して必要なコントローラーを見つけるか、見つからない場合はリンクfnにnullを渡します。
あなたの場合、require: '?^box',
とrequire: '?^^box',
require
は、必要な(親)ディレクティブから現在のディレクティブにコントローラーを注入します(angular docs: "require-Require a require directive and inject as the 4番目の引数としてリンク機能へ」 http://docs.angularjs.org/guide/directive )
それで、おそらくあなたはすでにあなたが望むものを手に入れていますか?つまり、親コントローラーはcontroller
パラメーターを介して子に注入されます。