AngularJS + jQuery: how to make dynamic content work in angularjs

I am working on an Ajax application using both jQuery and AngularJS.

When I update the content (containing AngularJS bindings) of a div using the jQuery html function, AngularJS bindings do not work.

Below is the code of what I'm trying to do:

 $(document).ready(function() { $("#refreshButton").click(function() { $("#dynamicContent").html("<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>") }); }); 
 </style><script src="http://docs.angularjs.org/angular-1.0.1.min.js"></script><style>.ng-invalid { border: 1px solid red; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app=""> <div id='dynamicContent'> <button ng-click="count = count + 1" ng-init="count=0"> Increment </button> <span>count: {{count}} </span> </div> <button id='refreshButton'> Refresh </button> </div> 

I have dynamic content inside a div with the id #dynamicContent , and I have an update button that will update the contents of this div when I click on the update. The increment works as expected if I do not update the content, but after the update, the AngularJS binding stops working.

This may not be valid in AngularJS, but I originally built the application with jQuery and later started using AngularJS, so I cannot port everything to AngularJS. Any help in getting this working in AngularJS is greatly appreciated.

+80
jquery angularjs
Aug 02 2018-12-12T00:
source share
3 answers

You need to call $compile in the HTML string before embedding it in the DOM so that angular can bind.

In your violin, it would look something like this.

 $("#dynamicContent").html( $compile( "<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>" )(scope) ); 

Obviously, $compile needs to be injected into your controller for this to work.

See the $compile documentation for more details.

+113
Aug 02 2018-12-12T00:
source share

Another solution if you do not have control over dynamic content

This works if you did not load your element through a directive (that is, as in the example in the jsfiddles comments).

Wrap Your Content

Wrap your content in a div so you can select it if you are using jQuery . You can also use your own javascript to get your element.

 <div class="selector"> <grid-filter columnname="LastNameFirstName" gridname="HomeGrid"></grid-filter> </div> 

Use Angular Injector

You can use the following code to get a link to compile $ if you don't have one.

 $(".selector").each(function () { var content = $(this); angular.element(document).injector().invoke(function($compile) { var scope = angular.element(content).scope(); $compile(content)(scope); }); }); 

Summary

The original post seemed to suggest that you have a link to compile $. Obviously, this is easy when you have a link, but I am not, it was the answer for me.

One warning from previous code

If you use the asp.net/mvc package with a minimal script, you will have problems deploying in release mode. The problem occurs as an Uncaught: [$ injector: unpr] error, which is caused by a minifier clutter with the Angular javascript code.

Here is a way to fix it :

Replace the previous code snippet with the next overload.

 ... angular.element(document).injector().invoke( [ "$compile", function($compile) { var scope = angular.element(content).scope(); $compile(content)(scope); } ]); ... 

This caused a lot of grief for me before I brought it together.

+54
Jun 05 '14 at 11:15
source share

Addition to @ jwize answer

Because angular.element(document).injector() injector is not defined error So, I created a function that you can run after calling AJAX or when the DOM is changed using jQuery.

  function compileAngularElement( elSelector) { var elSelector = (typeof elSelector == 'string') ? elSelector : null ; // The new element to be added if (elSelector != null ) { var $div = $( elSelector ); // The parent of the new element var $target = $("[ng-app]"); angular.element($target).injector().invoke(['$compile', function ($compile) { var $scope = angular.element($target).scope(); $compile($div)($scope); // Finally, refresh the watch expressions in the new element $scope.$apply(); }]); } } 

use it by passing only the new element selector. like this

 compileAngularElement( '.user' ) ; 
+15
Nov 05 '15 at 7:26
source share



All Articles