Reputation: 1558
I recently came across this code when trying to create a recursive tree view in angular js:
testApp.directive('collection', function () {
return {
restrict: 'E',
replace: true,
scope: {collection: '='},
template: '<ul><member x-ng-repeat="member in collection" x-member="member"></member></ul>'
};
});
testApp.directive('member', function ($compile) {
return {
restrict: 'E',
replace: true,
scope: {member: '='},
template: '<li>{{member.title}}</li>',
link: function (scope, element, attrs) {
if (angular.isArray(scope.member.children)) {
$compile('<collection x-collection="member.children"></collection>')(scope, function (cloned, scope) {
element.append(cloned);
});
}
}
};
});
The directive is used in the HTML like so:
<div ng-controller="TestCtrl">
<collection collection="testList"></collection>
</div>
Where testList is an array of JSON objects in TestCtrl, for example:
$scope.testList = [
{text: 'list item 1'},
{text: 'list item 2', children: [
{text: 'sub list item 1'},
{text: 'sub list item 2'}
]},
{text: 'list item 3'}
];
This code works well, but the templates for the collection directive and the member directive are hard coded. I was wondering if there is a way to get the templates for collection and member from the html. Something like this:
<div ng-controller="TestCtrl">
<ul recurse="testList">
<li>{{member.text}}</li>
</ul>
</div>
The recurse directive would be a replacement for the collection directive but the template for recurse would the the <ul>
element it is attached to.
Likewise, the member directive's template would be created from the children of the <ul>
element; the <li>
element in this case.
Is this possible?
Thanks in advance.
Upvotes: 1
Views: 330
Reputation: 17413
In your directive you can use transclude: true
and define parts of your template in HTML. The directive template can include it using ng-transclude
.
Imagine this template:
<div my-list="testList">
<b>{{item.text}}</b>
</div>
In your directive you can use transclusion to control how your list items gets rendered:
module.directive('myList', function () {
return {
restrict: 'A',
transclude: true,
replace: true,
scope: {
collection: '=myList'
},
template: '<ul><li ng-repeat="item in collection"><div ng-transclude></div><ul><li ng-repeat="item in item.children"><div ng-transclude></li></ul></li></ul>'
};
});
Upvotes: 1