I'm new to AngularJS, but I am really enjoying working with it so far. I have used AngularJS's ng-repeat to create tree structures in HTML where the children of a node a placed within a node's markup, like this:
<div class="parent">
I am the parent node.
<div class="child">
I am a child node.
<div class="child">
I am a grandchild.
etc...
</div>
</div>
</div>
but what I'd like to do instead is use the same data (a tree) to make some markup like this:
<div class="parent">I am the parent</div>
<div class="child">I am a child</div>
<div class="child">I am a grandchild</div>
<div class="child">I am a great-grandchild</div>
etc....
I.e., a list. The only way I have come up with to do this is by creating a new method on my container object called visibleDescendants, which makes an array and looks a lot like this:
this.visibleDescendants = function(a) {
if (!a) a = [];
if (this.selected()) {
a.push(this);
if (this.hasChildren()) {
this.children().forEach(function(child) {
if (child.selected()) {
a = child.visibleDescendants(a);
}
});
}
}
return a;
};
and then setting up the controller/template like this:
$scope.visibleDescendants = $scope.container.visibleDescendants();
<div ng-repeat="column in visibleDescendants">...</div>
and then every time one of the nodes is set to selected(false), I reset $scope.visibleDescendants.
That doesn't seem very efficient, and not very idiomatic, either, compared to other stuff I've been reading about/doing with AngularJS. I would like to be able to figure out a way to do this more declaratively in the template partial instead. Please help!
I think what I'm really trying to do is a matter of presentation and shouldn't affect the markup. In other words, the data and the markup ought to match structurally/semantically; only the CSS should change its appearance.
That said, I don't think it's wise to mess with restructuring the data for presentation purposes.