Kiran Kumar Kiran Kumar - 12 days ago 5
AngularJS Question

ng-click not working from dynamically generated HTML

HTML

<table data-ng-table="tableParams" class="table table-bordered table-hover " style="border-collapse:collapse" data-ng-init="host.editSave = false" >
<tr id="newTransaction">
</tr>
<tr data-ng-repeat="host in hosts|filter:search:strict" >
<td class="hostTableCols" data-ng-hide="host.editSave">{{host.hostCd}}</td>
<td class="hostTableCols" data-ng-hide="host.editSave">{{host.hostName}}</td>
</tr>
</table>


Jquery

$('#newTransaction').append(
'<td contenteditable><input type="text" class="editBox" value=""/></td>'+
'<td contenteditable><input type="text" class="editBox" value=""/></td>'+
'<td>'+
'<span>'+
'<button id="createHost" class="btn btn-mini btn-success" data-ng-click="create()"><b>Create</b></button>'+
'</span>'+
'</td>'
);


Angular Script

$scope.create = function() {
alert("Hi");
};


Here the function called in the controller part of the AngularJS is not getting trigger from the ng-click event. The Html is getting appended successfully, but the ng-click is not working. Tell me solutions to make it work

Answer

To make ng-click to work we need to compile this source by using $compile service.

See Fiddle

Create "compilator":

.directive( 'compileData', function ( $compile ) {
  return {
    scope: true,
    link: function ( scope, element, attrs ) {

      var elmnt;

      attrs.$observe( 'template', function ( myTemplate ) {
        if ( angular.isDefined( myTemplate ) ) {
          // compile the provided template against the current scope
          elmnt = $compile( myTemplate )( scope );

            element.html(""); // dummy "clear"

          element.append( elmnt );
        }
      });
    }
  };
});

after, create dummy factory that simulates your append:

.factory( 'tempService', function () {
  return function () { 
    return '<td contenteditable><input type="text" class="editBox" value=""/></td>'+ 
            '<td contenteditable><input type="text" class="editBox" value=""/></td>'+
             '<td>'+
                '<span>'+
         '<button id="createHost" class="btn btn-mini btn-success" data-ng-click="create()"><b>Create</b></button>'+
              '</span>'+
            '</td>';
  };
});

And finally call it like:

<div compile-data template="{{mainPage}}"></div> 

in Controller:

$scope.newTransaction= tempService();

For your example should be something like:

<table data-ng-table="tableParams" class="table table-bordered table-hover " style="border-collapse:collapse" data-ng-init="host.editSave = false" >
    <tr compile-data template="{{newTransaction}}">
    </tr>
    <tr data-ng-repeat="host in hosts|filter:search:strict" >
       <td class="hostTableCols" data-ng-hide="host.editSave">{{host.hostCd}}</td>
       <td class="hostTableCols" data-ng-hide="host.editSave">{{host.hostName}}</td>
    </tr>
</table>

BTW, for now you can use the same directive over your code and compile any dynamic HTML.

Comments