2

I'm using BootGrid Data table and JSON file as my data source for the table.

Service

.service('datatableService', ['$resource', function($resource){
        this.getDatatable = function(id, email, date) {
            var datatableList = $resource("data/data-table.json");

            return datatableList.get ({
                id: id,
                email: email,
                date: date
            })
        }
    }])

Controller

.controller('datatableCtrl', function($scope, datatableService){

        //Get Data Table Data
        $scope.id = datatableService.id;
        $scope.email = datatableService.email;
        $scope.date = datatableService.date;

        $scope.dtResult = datatableService.getDatatable($scope.id, $scope.email, $scope.date);


    })

Directive

.directive('bootgrid', ['$timeout', function($timeout){
    return {
        restrict: 'A',
        link: function(scope, element, attr){
            $('#data-table-basic').bootgrid({
                css: {
                    icon: 'md icon',
                    iconColumns: 'md-view-module',
                    iconDown: 'md-expand-more',
                    iconRefresh: 'md-refresh',
                    iconUp: 'md-expand-less'
                }

            });
        }   
    }
}])

HTML

<div class="table-responsive" data-ng-controller="datatableCtrl">
        <table id="data-table-basic" class="table table-striped" data-bootgrid>
            <thead>
                <tr>
                    <th data-column-id="id" data-type="numeric">ID</th>
                    <th data-column-id="sender">Sender</th>
                    <th data-column-id="received" data-order="desc">Received</th>
                </tr>
            </thead>
            <tbody>
                <tr data-ng-repeat="w in dtResult.list">
                    <td>{{ w.id }}</td>
                    <td>{{ w.email }}</td>
                    <td>{{ w.date }}</td>
                </tr>
            </tbody>
        </table>
    </div>

When I run this, I'm getting no data inside <tbody> but when I remove the directive, I can see all the JSON data are rendered inside the table. I want both ng-repeat and and directive works together. I tried to set the priority in directive as,

...
   return {
        restrict: 'A',
        priority: 1001,
        ...

But no luck. http://plnkr.co/edit/rWCVXTjxOGZ49CeyIn9d?p=preview

Please help me fix this. I would appropriate if you could fix the above pen.

Regards

Body
  • 3,608
  • 8
  • 42
  • 50

1 Answers1

1

Priority setting will not help here because it is used to regulate order of compilation of directives defined on the same element.

You can delay bootgrid directive initialization until very next digest cycle using $timeout service. You will also need to watch for data object changes since you are loading it with AJAX.

app.directive('bootgrid', function($timeout) {
    return {
        link: function(scope, element, attr) {
            scope.$watch(attr.bootgrid + '.length', function(newVal, oldVal) {
                if (newVal !== oldVal && newVal) {
                    $timeout(function() {
                        element.bootgrid({
                            css: {
                                icon: 'md icon',
                                iconColumns: 'md-view-module',
                                iconDown: 'md-expand-more',
                                iconRefresh: 'md-refresh',
                                iconUp: 'md-expand-less'
                            }
                        });
                    });
                }
            });
        }
    }
});

Demo: http://plnkr.co/edit/ehbzoFGOqhQedchKv0ls?p=preview

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • Thank you for the reply. Your method works, when I'm using local data. When call the data from a JSON file like my example above, it's not working. – Body May 25 '15 at 20:32
  • This is cool. I got 2 doubts. This means , scope.$watch(attr.bootgrid + '.length', function(newVal, oldVal) { Are you looking for any changes in attributes here,
    – Body May 25 '15 at 21:18
  • And could you please explain me the extra codes you've added here datatableService.getDatatable($scope.id, $scope.email, $scope.date).$promise.then(function(data) { this.datalist = data; }.bind(this)); – Body May 25 '15 at 21:20
  • No, it watches for changes in data array length. Initially it's undefined, because array is not defined, when it's loaded it will be different. Angular evaluate in scope context the value of the string supplied to `$watch`. – dfsq May 25 '15 at 21:21
  • Data binding is not working correctly. If datalist is changed in later time, grid does not reflect the changes – Samir Das May 26 '15 at 08:02
  • @Samir It depends on the plugin, how it needs to reinitialize/refresh grid. I implemented simple watcher which reacts only to data array length change, this way it much more performant. If actual data items deep structure changes need to be watched too then deep watching over collection is necessary, either with `true` argument to `$watch` of `$watchCollection`. – dfsq May 26 '15 at 08:11
  • @dfsq I understood but it is not a problem with `$watch` or `$watchCollection`. Problem with `bootgrid()` and the way it has been implemented. `bootgrid` spoils the `ng-repeat`s transcluded DOM content. So ng-repeat will never work after `bootgrid()` generation once – Samir Das May 26 '15 at 08:16