我想访问父指令的范围,但我似乎无法获得正确的设置组合。这是可能的,这是正确的方法吗?
我真的想避免在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
由于
答案 0 :(得分:42)
使用transclude: true
和scope: true
,parent
指令会创建两个新范围:
范围004是scope: true
的结果,范围005是transclude: true
的结果。由于child
指令不创建新范围,因此它使用了被转换的范围005.从图中可以看出,没有从范围005到范围004的路径(除了通过私有属性$$ prevSibling,它进入与$$ nextSibling相反的方向 - 但不要使用它们。)
@ joakimbl的解决方案在这里可能是最好的,虽然我认为在父指令的控制器上定义API更常见,而不是在this
上定义属性:
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();
},
这是tabs
和pane
指令在Angular主页上的工作方式(“创建组件”示例)。
答案 1 :(得分:9)
通常,您在指令中访问父作用域变量的方式是通过指令配置中的双向绑定(scope:{model:'=model'}
- 请参阅the angular guide on directives),但由于您使用的是transclusion,这是不那么直截了当。如果child指令始终是父指令的子指令,则可以将其配置为需要父指令,然后在子链接函数中访问父控制器:
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/
答案 2 :(得分:6)
我遇到了同样的问题,最后用角度手册解决了;)
简而言之:您需要在父指令中使用控制器,要求 >> 中的控制器 子指令。这样您就可以获得父属性。
参见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',
}
});
答案 3 :(得分:0)
在控制器之后的链接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
}
});