Reputation: 53
I have a serious problem. I must implement a table view with some combined data. I must show some data in a table row and following rows must be some details about this row. More than that, the user should be able to hide details clicking on the row.
For example, the model is name and surname oа some person. He has children, and their names must be shown in next rows after his name. According to my model, children names are stored in their dad's property, which is an array of objects similar to itself. Children can't have other children.
The trouble is that i can't process several table rows in one single run of the ngRepeat loop. I also tried to add another directive to the , it didn't help, as ng-repeat's transclude is set to 'element'. After that i tried to modify the ng-repeat directive, and almost achieved the result, but i had to create elements in the middle of the directive compile function. This is a very bad idea, as the code becomes very dirty and will be difficult to support.
This is how i modified the ng-repeat directive: (showing only part that changed)
if (!last) {
linker(childScope, function(clone){
var el = clone; //angular.element(template);
cursor.after(el);
if (!childScope.item.innerHidden) {
for (var i = 0; i < childScope.item.innerItems.length; i++) {
var innerItem = childScope.item.innerItems[i];
console.log(innerItem);
var elem = angular.element('<tr><td>' + innerItem.value1 + '</td><td>' +
innerItem.value2 + '</td></tr>');
el.after(elem);
el = elem;
}
}
last = {
scope: childScope,
element: (cursor = el),
index: index
};
nextOrder.push(value, last);
});
}
What could i do? I was thinking of some html tag that could be child of and parent of , is that possible? I could apply ng-repeat to it and manage my table rows inside it. Or are there other interesting possibilities?
Upvotes: 0
Views: 750
Reputation: 945
I would place the outer ng-repeat on a tbody tag. A table can contain multiple tbody and it will allow you to have multiple rows sharing the same object. For the hiding of children rows, there are multiple option. I chose an easy one in my example. It's probably not the best one since it polute the model with a flag for the view but it will give you a nice idea of how to do this.
Let's say this is your model :
$scope.family = [
{
name : 'Bob',
age : 34,
children : [
{
name: 'Robert',
age: 12
},
{
name: 'Paul',
age: 10
}
],
show:true
},
{
name : 'Mike',
age : 23,
childrens : [],
show:true
}
]
You will notice the show attribute. It's used for the view row hiding trick... as I said, you should find a better way to do this.
To display the data, use this table :
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody ng-repeat="person in family">
<tr ng-click="showChildren(person)">
<td>{{person.name}}</td>
<td>{{person.age}}</td>
</tr>
<tr class="child" ng-show="person.show" ng-repeat="child in person.children">
<td>{{child.name}}</td>
<td>{{child.name}}</td>
</tr>
</tbody>
</table>
You might notice the ng-click on the first tr and the ng-show on the second tr. This is where the magic happen to hide the nested rows. Just add this method in your controller and it will work!
$scope.showChildren = function(person){
person.show = !person.show;
}
Anyway... Check this plunker... it's a working example. Easier to understand!
Upvotes: 2