Reputation: 3623
If a
and b
are my directives such that b
is a child element of a
:
<a>
<b></b>
</a>
Is it possible that if a
has an isolated scope, then b
could inherit from it?
Example js:
app.directive('a', function () {
return {
restrict: 'E',
scope: {},
controller: function ($scope) {
$scope.prop1 = ...
}
}
});
app.directive('b', function () {
return {
restrict: 'E',
controller: function ($scope) {
//how to access $scope.prop1 here?
}
}
});
With this, I'm trying to make directives that are reusable and are supposed to be used as nested within each other.
I know that I can require
the controller of a
on directive b
to access it within the link function of b
as one way to share the data between controllers, but that approach isn't working very well if I have more than one level of nesting.
Upvotes: 2
Views: 1535
Reputation: 49590
This is where you need to use the manual transclusion function. If the parent directive has an isolate scope, the child DOM elements (and their directives) would not inherit from it (only, if they were in its template).
When you transclude, you can specify the scope explicitly:
.directive("a", function(){
return {
scope: {},
transclude: true,
link: function(scope, element, attrs, ctrls, transclude){
var newScope = scope.$new();
transclude(newScope, function(clone){
element.append(clone);
})
}
};
});
You should note, though, that although the above would work (in the sense that the child directive's scope would inherit the parent's isolate scope), it is also a somewhat confusing experience to the user of your directive.
To see why, imagine that a
exposes some $innerProp
on its scope. The user of a
now has to know that such property is "magically" available. This makes the HTML less readable without knowing a lot about a
:
<a>
<b item="$innerProp"></b>
</a>
Addendum
Depending on your use case, there might be other approaches that are more suitable. The above approach works better when a
and b
are independent, and when a
uses its contents to allow its user to specify some template.
If b
is only (or mostly) used as a child of a
, then it should require
it. a
can expose whatever it needs via its controller API to b
.
Lastly, if a
has a well-defined structure, then it should use its template
to specify b
. In your example, this could easily be achieved with a template.
Upvotes: 2