Jose Rocha
Jose Rocha

Reputation: 1115

Angular table directive ng-repeat

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,

Plunker

Upvotes: 1

Views: 684

Answers (1)

Isaac Lyman
Isaac Lyman

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

Related Questions