0

Description

I'm using AngularJS
I have a table that I want to show it as "Data Table" using DataTable jQuery plugin (http://datatables.net/docs/DataTables/1.9.4/DataTable.html).

The logic

  1. Create table table markup.
  2. Add ng-repeat using $scope.entities on the row .
  3. Run the plugin on the table.

The problem

In the first time that I run it, everything is OK.
The problem start when I need to change the $scope.entities (For example: user select another list)

In the snippets below I was created simpler scenario but the logic is same.

Steps

  1. Run the snippet (probably done automatic).
  2. Click on destroy button. It will destroy the plugin and return the table to original html.
  3. Click on Add row. It should add row to the table The problem is that all the rows were deleted instead of adding the row.

Note I saw some angular directives who integrating with the plugin (datatable). I can't using it. I need to understand why the view nodes are deleting.

angular.module('myApp', []).
controller('ctrl', function($scope, $timeout) {
  $scope.test = 'test';
  
  $scope.generateData = function() { 
    var temp = [];
    for (var i = 0; i < 5; i++) {
      temp.push({
        d1: Math.floor(Math.random() * 10),
        d2: Math.floor(Math.random() * 10),
        d3: Math.floor(Math.random() * 10)
      });
    }
    
    $scope.entities = temp;
    $timeout(function(){
      $scope.dt();  
    });
  };
  
  $scope.dt = function(){
    $timeout(function() {
      if (!$scope.dataTable) {
        $scope.dataTable = $('table').dataTable();  
      }
    });
  }
  
  $scope.destroy = function(){
    if ($scope.dataTable) {
        $scope.dataTable.fnDestroy();
      }
  }
  
  $scope.addRow = function(){
    $scope.entities.push({
        d1: Math.floor(Math.random() * 10),
        d2: Math.floor(Math.random() * 10),
        d3: Math.floor(Math.random() * 10)
      });
  }
  
  $scope.generateData();
});
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<link href="//cdn.datatables.net/1.9.4/css/jquery.dataTables.css" rel="stylesheet" />
<script src="//cdn.datatables.net/1.9.4/js/jquery.dataTables.min.js"></script>

<div data-ng-app="myApp" data-ng-controller="ctrl">
  <table>
    <thead>
      <tr>
        <th>Col1</th>
        <th>Col2</th>
        <th>Col3</th>
      </tr>
    </thead>
    <tbody>
      <tr data-ng-repeat="entity in entities">
        <td data-ng-bind="entity.d1"></td>
        <td data-ng-bind="entity.d2"></td>
        <td data-ng-bind="entity.d3"></td>
      </tr>
    </tbody>
  </table>
    <button data-ng-click="destroy();">Destroy</button>
    <button data-ng-click="addRow();">Add rows</button>
</div>

1 Answer 1

1

I believe the issue is you have your ng-repeat upon the <tr> element. Calling fnDestroy() seems to to delete and re-insert all the original elements in the DOM.

I believe because of this Angular looses reference to the template and it was as if the ng-repeat was never there in the first place. As Angular is not removing and creating the new elements itself. Adding {{entities}} in your markup show that the array is correct and that the new item is being added.

I'm not familiar with data tables so don't know if it has events etc that you need to destroy with fnDestroy() but could you not empty the entities array instead so that angular removes the table? Thus not loosing its bindings? Or will the structure of the table change, different number of headers etc.

EDIT: Found this post on the data tables forums. Apparently you can use the data tables API to manipulate the table, add, remove rows etc. They advise, and i agree, that you shouldn't have multiple libraries manipulating the DOM. One option is to have Angular instruct data tables what to do with the table and let data tables actually manipulate it. You could wrap this in your own minimal directive or service also.

https://www.datatables.net/forums/discussion/21286/datatables-and-angularjs#Comment_61703

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.