Reputation: 5024
I need to conditionally use a child directive inside a parent directive.
I'm using $compile
to compile a template for a child directive in parent directive's link
function, and the child directive has its own isolated scope.
The problem is that an ng-click
on the child directive is invoked in the parent scope when the child directive's element is clicked.
Here is an SSCCE:
var app = angular.module("test", []);
app.directive("parentDirective", function($compile) {
return {
restrict: "EA",
scope: {},
link: function(scope, element, attrs) {
element.append('!');
scope.foo = function() {
alert('parent foo');
};
var childTemplate = "<div child-directive ng-click='foo()'>Child directive</div>";
element.append($compile(childTemplate)(scope));
}
};
});
app.directive("childDirective", function() {
return {
restrict: "EA",
scope: {},
link: function(scope, element, attrs) {
scope.foo = function() {
alert('child foo!');
};
element.append('!');
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app="test">
<div parent-directive>Parent directive</div>
</div>
The ng-click=foo()
should invoke foo
from the child scope, however it's invoking the parent foo
. If you click Child directive!
div you get Parent foo
alert.
Why is that so and how can I make it work as expected?
Upvotes: 2
Views: 653
Reputation: 21901
this issue is regarding scope of compiling the template.
check this PLUNKER
alert('init parent directive -1');
will called then the alert('init child directive');
and finally alert('init parent directive-2');
that means in line 20
in the plunker example, parent directive link function create a child-directive
but the that directive compile against the parent directive scope
not the scope of the child directive
, so the $compile()
can only see anything inside the parent directive scope
cant see about the child scope
.
if you need to attach child scope
then you have to compile it inside the child directive
. or better to use template
or templateUrl
in the child directive
.
Upvotes: 2
Reputation: 41
var app = angular.module("test", []);
app.directive("parentDirective", function($compile) {
return {
restrict: "EA",
template: "<div ng-click='foo()'>Parent directive!</div>", //You can use templateUrl as well
scope: {},
link: function(scope, element, attrs) {
scope.foo = function() {
alert('parent foo');
};
var childTemplate = "<child-directive/>";
element.append($compile(childTemplate)(scope));
}
};
});
app.directive("childDirective", function() {
return {
restrict: "EA",
template: "<div ng-click='foo()'>Child directive!</div>",
scope: {},
link: function(scope, element, attrs) {
scope.foo = function() {
alert('child foo!');
};
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app="test">
<parent-directive/>
</div>
Try this
Upvotes: 0