1

I have a DataTable and I am loading it using Angular Js, I have Created a directive and wrapped my DataTable in this directive, A common approach of wraping JQuery Plugin in Directive so that it can live in Angular Digest Cycle. But the ng-click that is on button and coming from render Function of column in datatable is not clickable (Not Working, Angular did not compiled it). Is there any way to make it Clickable. I know the approach in which we use {{}} with ng-repeatto populate data in datatable. I'm looking a directive way, so you can tell me what is stoping ng-click from working or how to make my directive right! Please stick with directive approach. Code is following.

App.directive('jqtable', function () {
return {
    restrict: 'E, A, C',
    link: function (scope, element, attrs, controller) {
        var dataTable = element.dataTable(scope.options);
         scope.$watch('options.data',  handleModelUpdates, true);
            function handleModelUpdates(newData) {
            var data = newData || null;
            if (data) {
                dataTable.fnClearTable();
                dataTable.fnAddData(data);
            }
        }
    },
    scope: {
        options: "="
    }
};

});

And here is my Controller:-

$scope.options = {
   aoColumnDefs: [{
        "bSortable": true,
        "aTargets": [ 1],
        "render": function ( data, type, full, meta ) {
            if(meta.col==1){
                return data+" <a class='btn btn-sm btn-default' ng-click='showalert()' >Click me </a>"
            }
        }
    }],
    bJQueryUI: true,
    bDestroy: true,
    data:$scope.data                        
};
$scope.showalert=()=>
{
    alert("Angular Compiled the Html");
}

1 Answer 1

2

Angular does not know you have injected elements to the DOM. You must $compile each row. You can do that in rowCallback. Since DataTables may inject new rows when the table is filtered, sorted or upon page change, you can add a compiled flag to prevent rows from being $compiled multiple times :

$scope.options = {
  rowCallback: function(row) {  
    if (!row.compiled) {
      $compile(angular.element(row))($scope);
      row.compiled = true;  
    }  
  }
  ...
}

see http://next.plnkr.co/edit/KxwqSVXIogtXYx4I

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

5 Comments

Thanks but i already solved problem and its in pure Angular JS way. I appreciate your help.` drawCallback function` seems interesting. And also when using angular Js one should not rely on Jquery because its not a good approach to cut shortcut.I hope you will understand from where I am coming. And kindly explain drawCallback function.It's a new way to invoke compile function to me. I hope you won't mind investing your time in explaining how it actually works in browser.
@ahsanayub, I have altered the answer completely. Sorry for the confusion (I am nnormally using angular datatables). I realized that drawCallback is a no go since you will end up having rows $compiled' n times. Use rowCallback instead and set a flag on each row when it is compiled. DataTables injects and removes rows to and from the DOM all the time, so drawCallback is not very useful.
The solution i came up with was, Let the table populate and then invoke $compile function to run the $digest again. Though, its rare in angular but it becomes necessary if you are using Jquery plugins and adding something to DOM dynamically. Thanks for creating plunker, it really helped me, understanding the idea behind your approach. I accept your answer, Thanks! @davidkonrad
@ahsanayub, Thank you for accepting the answer, but if you have a better answer I think you should post that answer and mark that as accepted instead. Perhaps it will help future visitors
your answer is better! Its simple and approachable. I would have posted my answer but i think it will only make people confuse and its also requires a bit of tuning.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.