Reputation: 1115
Hy,
I created a directive for a simple use of tables in my application. I'm struggling to get an ng-repeat to work. The problem is that my directive will tell the table from what controller it will get the list with the data for the ng-repeat and this seems not to work, i could use another directive to create an ng-repeat but i don´t want to change the way the developer can use the angular directives.
So if anyone already struggled with this problem please share how you resolve it.
this is the markup.
<body ng-app="List">
<div my-table pl-emptytext="No data found!">
<table>
<thead>
<tr>
<th pl-sort="Id"> Id </th>
<th pl-sort="Name"> Name </th>
<th pl-sort="Roles"> Roles </th>
<th pl-sort="Claims"> Claims </th>
</tr>
</thead>
<tbody>
<tr pl-obj="user">
<td>{{user.Id}}</td>
<td>{{user.Name}}</td>
<td>
<span ng-repeat="role in user.Roles">
{{role.RoleType}}
</span>
</td>
<td>
<span ng-repeat="claim in user.Claims">
{{role.ClaimType}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
</body>
This is the directive myTable
angular
.module('List')
.directive('myTable', [
'$compile',
function($compile) {
return {
restriction: 'AE',
scope: {
plEmptytext: '@'
},
transclude: true,
replace: true,
template: '<div class="container-fluid">' +
'<div class="row">' +
'<div class="col-lg-12">' +
'<div class="alert alert-warning" ng-cloak ng-show="ListIsEmpty">' +
'{{plEmptytext}}' +
'</div>' +
'<div ng-transclude></div>' +
'</div>' +
'</div>' +
'</div>',
link: function(scope, element) {
// Do something else, bind events, etc ...
var table = element.find('table');
$compile(table)(scope);
}
};
}
])
.directive('table', [
function() {
return {
link: function(scope, element, attrs) {
attrs.$addClass("table");
attrs.$addClass("table-striped");
}
};
}
])
.directive('thead', [
function() {
return {
link: function(scope, element, attrs) {
}
};
}
])
.directive('th', [
function() {
return {
link: function(scope, element, attrs) {
if (attrs.plSort) {
attrs.$set("ngClick", "resort('" + attrs.plSort + "')");
}
}
};
}
])
.directive('tbody', [
function() {
return {
link: function(scope, element, attrs) {
attrs.$set("ng-controller", "listCtrl");
}
};
}
])
.directive('tr', [
function() {
return {
link: function(scope, element, attrs) {
if (attrs.plObj) {
attrs.$set("ngRepeat", attrs.plObj + " in List");
}
}
};
}
]);
And this is the listCtrl
angular.module('List', [])
.controller('listCtrl', ['$scope', '$timeout',
function($scope, $timeout) {
$timeout(function() {
$scope.List = [{
Id: '1',
Name: 'teste1',
Roles: [{
Id: 1,
RoleType: '1'
}, {
Id: 2,
RoleType: '2'
}],
Claims: [{
Id: 1,
CalimType: '1'
}, {
Id: 2,
ClaimType: '2'
}]
}, {
Id: '1',
Name: 'teste1',
Roles: [{
Id: 2,
RoleType: '2'
}],
Claims: [{
Id: 2,
ClaimType: '2'
}]
}];
}, 1000)
}
]);
The problem is when i try to call the ng-repeat on this 2 td it dosen´t work
<td>
<span ng-repeat="role in user.Roles">
{{role.RoleType}}
</span>
</td>
<td>
<span ng-repeat="claim in user.Claims">
{{role.ClaimType}}
</span>
</td>
Anyone can point me in the direction of the problem? Already look to different things and different solutions from different people, yet it seems that no one had face my problem.
Best,
Upvotes: 1
Views: 684
Reputation: 2205
First of all, your pl-obj
directive is literally just an ng-repeat
. So use <tr ng-repeat="user in List">
.
Second of all, your controller doesn't appear to be hooked up. You're trying to hook it up using a strange directive, but you may be doing it in a way Angular doesn't understand (properties of the attrs
object are camelCased, not hyphen-ated). Just use an ng-controller
attribute on your table
element: <table ng-controller="listCtrl">
.
Once you're using more standard Angular in this way, I expect your problem will be easier to troubleshoot.
EDIT: Here's a Plunker with the changes I recommended (and some corrected typos). https://plnkr.co/edit/iEEtBycevB3Wh6eHFEAI?p=preview. Seems to work fine now.
EDIT 2: If you want to use the same controller for all <tbody>
(I don't recommend this, but it's something you can do), use this in your directive:
function() {
return {
controller: 'listCtrl',
...
};
}
Upvotes: 1