0

I have an AngularJS phonegap application, where the HTML is just a blank table that is being filled up dynamically by JS Ajax. Ajax brings the required data and fills the table by using innerHTML. In my case, the table is filled with multiple buttons and each button has an ng-click method name:

$.ajax({
   type: 'GET',
   dataType: 'json',
   url: 'SAMPLEURL'+tID,
   contentType: 'application/json;charset=utf-8',
   success: function(response){
       var reqObject = JSON.parse(response);


       var tableHtml = "";
        for(i = 1;i<reqObject.object.length; i++)
           {
             var variant = reqObject.variants[i];
               tableHtml += "<tr><td>";
               tableHtml += "<button type='button' ng-click=\"calculateQuantity();\" class='buttonStandard' id='"+variant.Id+"' style='padding:10px 15px 20px 15px; width:100%;margin-top:-10px;'>";


               tableHtml += "<div style='height:40px'><h4>"+variant.Name+"</h4></div>";
               tableHtml += "</button>";
               tableHtml += "</td></tr><tr><td><br /></td></tr>";
           }

       document.getElementById("tableSelection").innerHTML = tableHtml;

       $scope.calculateQuantity = function() {
        alert('test');
      };

   },
   error: function(xhr){
       alert('Failed to bring Variants');
   }    
});

As you can see from the code above, I am also adding a method to the scope, called calculateQuantity and it should send an alert with 'test' when a user clicks on a button. Unfortunately this is not happening, anyone knows what I might be doing wrong?

NetUser101
  • 272
  • 2
  • 5
  • 20
  • 1
    You are retrieving extra data from jquery instead of $http. Angular will never know about the result unless you will tell angular the scope changed outside its reach. I recommend to do all ajax calls with angulars build-in $http service – Jasper Seinhorst Nov 07 '17 at 13:57
  • 1
    Thanks Jasper, I changed it to using the $http service, however the $compile was the answer to my problem. – NetUser101 Nov 08 '17 at 07:32

1 Answers1

2

if you are working with dynamically created elements so you need to use $compile to re compile your DOM before insert into HTML

Just change this line

document.getElementById("tableSelection").innerHTML = tableHtml;

to be

document.getElementById("tableSelection").innerHTML = $compile(tableHtml)($scope);

Don't forget to inject $compile into your controller

Note: you'd better use the angular.element which is implement jQuery light version rather than document.getElementById

angular.element(document.querySelector('#tableSelection')).append($compile(tableHtml)($scope))

Update: as Jasper Seinhorst said you also have another problem which is you are working outside the angular zone by using jQuery ajax, you have some options to go back the the angular zone which is wrapping your code into $timeout or to call $scope.$apply() in the response of your Ajax call. in addition to the option Jasper Seinhorst has said.

Peter Wilson
  • 4,150
  • 3
  • 35
  • 62