親ディレクティブのスコープにアクセスしたいのですが、設定の正しい組み合わせを取得できないようです。これは可能ですか、それは正しいアプローチですか?
MyCtrlにSOME_CONST(制御フローを介してDOM更新を行うのに役立ちます)のようなものを入れないようにしたい
<div ng-controller="MyCtrl">
<parent>
<child></child>
</parent>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.obj = {prop:'foo'};
}
myApp.directive('parent', function() {
return {
scope: true,
transclude: true,
restrict: 'EA',
template: '<div ng-transclude><h1>I\'m parent {{obj.prop}}<h1></div>',
link: function(scope, elem, attrs) {
scope.SOME_CONST = 'someConst';
}
}
});
myApp.directive('child', function() {
return {
restrict: 'EA',
template: '<h1>I\'m child.... I want to access my parent\'s stuff, but I can\'t. I can access MyCtrlScope though, see <b>{{obj.prop}}</b></h1> how can I access the <b>SOME_CONST</b> value in my parent\'s link function? is this even a good idea? {{SOME_CONST}}. I really don\'t want to put everything inside the MyCtrl',
}
});
こちらをご覧ください fiddle
ありがとう
transclude: true
およびscope: true
を使用すると、parent
ディレクティブは2つの新しいスコープを作成します。
スコープ004はscope: true
の結果であり、スコープ005はtransclude: true
の結果です。 child
ディレクティブは新しいスコープを作成しないため、トランスクルードされたスコープ005を使用します。図からわかるように、スコープ005からスコープ004へのパスはありません(プライベートプロパティ$$ prevSiblingを除く$$ nextSiblingの反対方向に-しかし、それらを使用しないでください。
@joakimblのソリューションはおそらくここが最適です。ただし、this
でプロパティを定義するよりも、親ディレクティブのコントローラーでAPIを定義する方が一般的だと思います。
controller: function($scope) {
$scope.SOME_CONST = 'someConst';
this.getConst = function() {
return $scope.SOME_CONST;
}
}
次に、child
ディレクティブで:
link:function(scope,element,attrs,parentCtrl){
scope.SOME_CONST = parentCtrl.getConst();
},
これは、Angularのホームページでtabs
およびpane
ディレクティブがどのように機能するかを示しています(「コンポーネントの作成」の例)。
通常、ディレクティブで親スコープ変数にアクセスする方法は、双方向バインディング(scope:{model:'=model'}
- ディレクティブ設定のangularディレクティブのガイド )を参照)が、トランスクルージョンを使用しているため、これはそれほど単純ではありません。ただし、子ディレクティブが常に親ディレクティブの子になる場合は、親を要求するように構成してから、子リンク関数で親コントローラーにアクセスできます。
myApp.directive('parent', function() {
return {
scope: true,
transclude: true,
restrict: 'EA',
template: '<div ng-transclude><h1>I\'m parent {{obj.prop}}<h1></div>',
controller: function($scope) {
$scope.SOME_CONST = 'someConst';
this.SOME_CONST = $scope.SOME_CONST;
}
}
});
myApp.directive('child', function() {
return {
restrict: 'EA',
require:'^parent',
scope:true,
link:function(scope,element,attrs,parentCtrl){
scope.SOME_CONST = parentCtrl.SOME_CONST;
},
template: '<h1>I\'m child.... I want to access my parent\'s stuff, but I can\'t. I can access MyCtrlScope though, see <b>{{obj.prop}}</b></h1> how can I access the <b>SOME_CONST</b> value in my parent\'s link function? is this even a good idea? {{SOME_CONST}}. I really don\'t want to put everything inside the MyCtrl',
}
});
この更新を参照してください: http://jsfiddle.net/uN2uv/
私はちょうど同じ問題を抱えていて、angular manual;)で最終的に解決しました
要するに:controller inyourparentディレクティブとrequireそのコントローラーinyour childディレクティブ。これにより、親プロパティを取得できます。
https://docs.angularjs.org/guide/directive を参照してください。章:通信するディレクティブの作成
コントローラーを使用するようにフィドルを変更し、定数にアクセスできるようになりました: https://jsfiddle.net/bbrqdmt3/1/
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.obj = {prop:'foo'};
}
myApp.directive('parent', function() {
return {
scope: true,
transclude: true,
restrict: 'EA',
template: '<div ng-transclude><h1>I\'m parent {{obj.prop}}<h1></div>',
controller: function($scope) {
this.getConst= function() {
return 'someConst';
}
},
}
});
myApp.directive('child', function() {
return {
restrict: 'EA',
require : '^parent',
link: function(scope, element, attrs, ctrl) {
scope.value= ctrl.getConst();
},
template: '<h1>I\'m child.... I want to access my parent\'s stuff, but I can\'t. I can access MyCtrlScope though, see <b>{{obj.prop}}</b></h1> how can I access the <b>SOME_CONST</b> value in my parent\'s link function? is this even a good idea? {{value}}. I really don\'t want to put everything inside the MyCtrl',
}
});
コントローラの後のリンクfnの引数には、トランスクルードfnがあります。
myApp.directive('parent', function() {
return {
scope: true,
transclude: true,
restrict: 'EA',
template: '<div><h1>I'm a parent header.</h1></div>',
link: function (scope, el, attrs, ctrl, transclude) {
transclude(scope, function (clone, scope) {
element.append(clone); // <-- will transclude it's own scope
});
},
controller: function($scope) {
$scope.parent = {
binding: 'I\'m a parent binding'
};
}
}
});
myApp.directive('child', function() {
return {
restrict: 'EA',
require:'^parent',
scope:true,
link:function(scope,element,attrs,parentCtrl){
},
template: '<div>{{parent.binding}}</div>' // <-- has access to parent's scope
}
});