While going through some AngularJS examples, I see how easy it is to repeat and create structures. However, I couldn't figure out how to do the following.
Assume we have a json structure like
{
"Asia": {
"India": {
"Bangalore": {},
"Mumbai": {},
"New Delhi": {}
},
"China": {
"Beijing": {},
"Shanghai": {}
}
},
"Europe": {
"France": {
"Paris": {}
},
"Germany": {
"Berlin": {}
}
}
}
What I want to do is - Convert this JSON structure to an Unordered list - The depth of this kind of structure is not known, and can possibly go deeper. How do I perform repeats dynamically using Angular JS?
Your JSON is poorly structured, you're using property names to carry data.
What you really want is something like this:
$scope.continents = [
{
name: 'Asia',
countries: [
{
name: 'India',
cities: [
'Bangalore',
'Mumbai',
'New Delhi'
]
},
{
name: 'China',
cities: [
'Beijing',
'Shanghai'
]
},
]
},
{
name: 'Europe',
countries: [
{
name: 'France',
cities: [
'Peris'
]
},
{
name: 'Germany',
cities: [
'Berlin'
]
},
]
}
];
That said... what it sounds like you're looking to do is create a recursive tree directive of some sort. That gets a little tricky. You'll need to normalize your structure a bit so you can recursively examine it. Then you'll have to create two directives. One for a list, and one for an item:
Here is an example of what I mean...
function Item(name, items) {
this.name = name;
this.items = items || [];
}
app.controller('MainCtrl', function($scope) {
$scope.items = [
new Item('test'),
new Item('foo', [
new Item('foo-1'),
new Item('foo-2', [
new Item('foo-2-1'),
new Item('foo-2-2')
])
]),
new Item('whatever')
];
});
app.directive('tree', function() {
return {
template: '<ul><tree-node ng-repeat="item in items"></tree-node></ul>',
restrict: 'E',
replace: true,
scope: {
items: '=items'
}
};
});
app.directive('treeNode', function($compile) {
return {
restrict: 'E',
template: '<li>{{item.name}}</li>',
link: function(scope, elm, attrs) {
//MAGIC HERE!!!: this will do the work of inserting the next set of nodes.
if (scope.item.items.length > 0) {
var children = $compile('<tree items="item.items"></tree>')(scope);
elm.append(children);
}
}
};
});
In case anyone is interested in the "least-effort" way to do this without creating a directive (not that you shouldn't, but just offering a variation), here is a simple example:
http://jsbin.com/hokupe/1/edit
Also here's a blog post and a 10-15 minutes video on how it works:
http://gurustop.net/blog/2014/07/15/angularjs-using-templates-ng-include-create-infinite-tree/
Sample Code:
<script type="text/ng-template" id="treeLevel.html">
<ul>
<li ng-repeat="item in items">
<input type="checkbox"
name="itemSelection"
ng-model="item._Selected" />
{{item.text}}
<div ng-include=" 'treeLevel.html'"
onload="items = item.children">
</div>
</li>
</ul>
</script>
<div ng-include=" 'treeLevel.html' "
onload="items = sourceItems">
</div>