<!DOCTYPE html>
<html>

<head>
  <script data-require="angular.js@*" data-semver="1.2.11" src="http://code.angularjs.org/1.2.11/angular.js"></script>
  <script src="main.js"></script>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
  <div ng-app='myApp'>
    <div ng-controller="myCtrl">
      <ang-table conf="config"></ang-table>
    </div>
  </div>


</body>

</html>
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope) {

  $scope.config = {

    heads: ['name', 'age', 'company', 'tech'],
    myData: [{
      name: 'Jay',
      age: 27,
      company: 'ABC',
      tech: 'Js'
    }, {
      name: 'Rayn',
      age: 30,
      company: 'NBC',
      tech: '.net'
    }]
  };

});
myApp.directive('droppable', ['$parse',
  function($parse) {
    return {

      link: function(scope, element, attr) {

        function onDragOver(e) {

          if (e.preventDefault) {
            e.preventDefault();
          }

          if (e.stopPropagation) {
            e.stopPropagation();
          }
          e.dataTransfer.dropEffect = 'move';
          return false;
        }

        function onDrop(e) {
          if (e.preventDefault) {
            e.preventDefault();
          }
          if (e.stopPropagation) {
            e.stopPropagation();
          }
          var data = e.dataTransfer.getData("Text");
          
          data = angular.fromJson(data);

          var dropfn = attr.drop;
          var fn = $parse(attr.drop);
          scope.$apply(function() {

            scope[dropfn](data, e.target);
          });

        }



        element.bind("dragover", onDragOver);
        element.bind("drop", onDrop);




      }
    };


  }
]);
myApp.directive('draggable', function() {

  return {

    link: function(scope, elem, attr) {

      elem.attr("draggable", true);
      var dragDataVal='';
      var draggedGhostImgElemId='';
      attr.$observe('dragdata',function(newVal){
        dragDataVal=newVal;
        
      });
      
      attr.$observe('dragimage',function(newVal){
        draggedGhostImgElemId=newVal;
      });

      elem.bind("dragstart", function(e) {
        var sendData = angular.toJson(dragDataVal);
        e.dataTransfer.setData("Text", sendData);
        if (attr.dragimage !== 'undefined') {
          e.dataTransfer.setDragImage(
            document.getElementById(draggedGhostImgElemId), 0, 0
          );

        }

        var dragFn = attr.drag;
        if (dragFn !== 'undefined') {
          scope.$apply(function() {
            scope[dragFn](sendData);
          })

        }

      });


    }


  };


});
myApp.directive('angTable', ['$compile',
  function($compile) {
    return {
      restrict: 'E',
      templateUrl: 'tabletemplate.html',
      replace: true,

      scope: {
        conf: "="

      },
      controller: function($scope) {

        $scope.dragHead = '';
        $scope.dragImageId = "dragtable";


        $scope.handleDrop = function(draggedData,
          targetElem) {

          var swapArrayElements = function(array_object, index_a, index_b) {
            var temp = array_object[index_a];
            array_object[index_a] = array_object[index_b];
            array_object[index_b] = temp;
          };

          var srcInd = $scope.conf.heads.indexOf(draggedData);
          var destInd = $scope.conf.heads.indexOf(targetElem.textContent);
          swapArrayElements($scope.conf.heads, srcInd, destInd);

        };

        $scope.handleDrag = function(columnName) {

          $scope.dragHead = columnName.replace(/["']/g, "");

        };



      },
      compile: function(elem) {
        return function(ielem, $scope) {

          $compile(ielem)($scope);


        };


      }




    };


  }
]);
.hidtable {
    position: absolute;
    top: 0;
    left: 0;
    cursor:move;
    background:white;
    border-style:dotted;
    z-index:4;
}
.coverhidtable {
    position: absolute;
    top: 0;
    left: 0;
    cursor:move;
    background:white;
    color:white;
    z-index:4;
}
.acttable {
    position: absolute;
    top: 0;
    left: 0;
    cursor:move;
    z-index:5;
    background:white;
}
.drag {
    background:orange;
    color:white;
    cursor:move;
}
.over {
    background: red;
    color:white;
}

This is a simple example of reordering of columns in a table using angular directives.
Basically this application uses 3 directives, myTable, draggable and droppable.
The diective angTable is an element directive, where it has an attribute named conf
The attribute 'conf'may contain an object consisting of head where we specify the table headers and one array of objects.
Directive named draggable has 3 attributes:
  drag:which specify a function defined which get fired when the dragging starts
  dragData:which specify the text to be transfered as the content of dragged element
  dragImage:the id of the element which ghost image should appear as the drag feedback
Directive named droppable has 1 attributes:
  drop:which specify a function defined which get fired when the drop occurs  
<div style="position:relative">
  <table class="hidtable" id="dragtable" border="1">
    <thead style="cursor:move">
      <th>{{dragHead}}</th>
    </thead>
    <tr ng-repeat="row in conf.myData">
      <td>{{row[dragHead]}}</td>
    </tr>
  </table>
  <table class="coverhidtable" border="1">
    <thead style="cursor:move">
      <th>{{dragHead}}</th>
    </thead>
    <tr ng-repeat="row in conf.myData">
      <td>{{row[dragHead]}}</td>
    </tr>
  </table>
  <table class="acttable" border="1">
    <thead>
      <th style="cursor:move" draggable drag="handleDrag"  dragData="{{hd}}" dragImage="{{dragImageId}}" droppable drop="handleDrop" ng-repeat="hd in conf.heads"><span>{{hd}}</span>
      </th>
    </thead>
    <tbody>
      <tr ng-repeat="data in conf.myData">
        <td ng-repeat="d in conf.heads"><span>{{data[d]}}</span>
        </td>
      </tr>
    </tbody>
  </table>
</div>