Reputation: 1370
I want to use something like nesting with custom directives in angular js. Could anyone explain me with simple solution ?
example code is below is not working for me :
<outer>
<inner></inner>
</outer>
JS
var app = angular.module('app',[]);
app.directive('outer',function(){
return{
restrict:'E',
template:'<div><h1>i am a outer</h1></div>',
compile : function(elem,attr){
return function(scope,elem,att,outercontrol){
outercontrol.addItem(1);
}
},
controller : function($scope){
this.addItem = function(val){
console.log(val);
}
}
}
});
app.directive('inner',function(){
return{
require : 'outer',
template : '<div><h1>i am a inner</h1></div>',
link:function(scope,elem,attr){
}
}
});
Upvotes: 21
Views: 15930
Reputation: 4302
If you want a simple solution, check out this plunkr.
var app = angular.module('app',[]);
app.directive('outer', function() {
return {
restrict: 'E',
template: '<div style="border-style:solid"><h1>hey</h1><inner></inner></div>',
}
});
app.directive('inner', function() {
return {
restrict: 'E',
template: '<div style="border-style:solid"><h1>i am an inner</h1></div>',
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js"></script>
<div ng-app="app">
<outer></outer>
</div>
The problem is that you're nuking the tag with the template attribute of the directive. This line:
template:'<div><h1>i am a outer</h1></div>',
Does that.
Upvotes: 4
Reputation: 661
First add restrict:'E'
to the inner controller to make it accessible as an element.
Then change the require : 'outer'
into require : '^outer',
to enable looking for this directive in parents.
Then you need to use transclude to enable the content of the <outer>
to be viewed, by the following steps:
transclude = true
to the outer directive.template:'<div><h1>i am a outer</h1><div ng-transclude></div></div>'
).Then you don't need to the compile parameter at all. As this variable which called outercontrol will not be called at the outer directive but at the inner directive so there is no need to the compile at all for the outer directive and the inner link function will be modified to be like this:
link: function(scope, elem, attr, outercontrol){
outercontrol.addItem(1);
}
after all this modification the final code will be like the following:
the HTML:
<outer>
<inner></inner>
</outer>
the js:
var app = angular.module("exampleApp",[]);
app.directive('outer', function(){
return{
transclude:true,
restrict:'E',
template:'<div><h1>i am a outer</h1><div ng-transclude></div></div>',
controller : function($scope){
this.addItem = function(val){
console.log(val);
}
}
}
});
app.directive('inner',function(){
return{
restrict:'E',
require : '^outer',
template : '<div><h1>i am a inner</h1></div>',
link:function(scope,elem,attr,outercontrol){
outercontrol.addItem(1);
}
}
});
Upvotes: 47