#ソース
ng-templateを使用し、dirTree.htmlを再帰処理。
##html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js@*" data-semver="1.4.9" src="https://code.angularjs.org/1.4.9/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller="myCtrl">
<ul>
<li ng-repeat="data in tree" ng-include="'dirTree.html'"></li>
</ul>
</div>
<script type="text/ng-template" id="dirTree.html">
<a ng-if="!data.dir">{{data.file}}</a>
<span class="dir" ng-if="!!data.dir">{{data.dir}}</span>
<ul ng-if="!!data.dir">
<li ng-repeat="data in data.dirContents" ng-include="'dirTree.html'"></li>
</ul>
</script>
</body>
</html>
#script.js
jsonのキーにdirがある場合とfileがある場合で、処理を分けて再帰処理を実行。(↑のdirTree.htmlで)
var app = angular.module("app", []);
app.controller("myCtrl", ["$scope", function($scope){
$scope.tree = [
{"file": "file-A"},
{"dir": "dir-B","dirContents":[{"file": "fileB-1"},{"file": "fileB-2"},{"dir": "dirB-3","dirContents":[{"file": "fileB3-1"},{"file": "fileB3-2"}]}]},
{file: "file-C"}
];
}]);
カスタムディレクテイブでもいけそうだが、まずはこのやり方で。以下demoっす。
plnkr-demo