AngularJS + JQuery: cómo hacer que el contenido dynamic funcione en angularjs

Estoy trabajando en una aplicación Ajax usando jQuery y AngularJS.

Cuando actualizo contenido (que contiene enlaces AngularJS) de un div usando la función html de jQuery, los enlaces AngularJS no funcionan.

Lo siguiente es código de lo que estoy tratando de hacer:

 $(document).ready(function() { $("#refreshButton").click(function() { $("#dynamicContent").html("count: {{count}} ") }); }); 
 .ng-invalid { border: 1px solid red; } 
   
count: {{count}}

Tengo contenido dynamic dentro de un div con ID #dynamicContent , y tengo un botón de actualización que actualizaría el contenido de este div cuando se hace clic en la actualización. El incremento funciona como se espera si no actualizo el contenido, pero después de actualizarlo, el enlace AngularJS deja de funcionar.

Esto puede no ser válido en AngularJS, pero inicialmente construí la aplicación con jQuery y comencé a usar AngularJS más adelante, así que no puedo migrar todo a AngularJS. Cualquier ayuda para hacer que esto funcione en AngularJS es muy apreciada.

Debe invocar $compile en la cadena HTML antes de insertarlo en DOM para que angular tenga la posibilidad de realizar la vinculación.

En tu violín, se vería algo como esto.

 $("#dynamicContent").html( $compile( "count: {{count}} " )(scope) ); 

Obviamente, $compile debe ser inyectado en su controlador para que esto funcione.

Lea más en la documentación $compile .

Otra solución en caso de que no tenga control sobre el contenido dynamic

Esto funciona si no cargó su elemento a través de una directiva (es decir, como en el ejemplo en los jsfiddles comentados).

Envuelva su contenido

Envuelva su contenido en un div para que pueda seleccionarlo si está utilizando JQuery . También puede optar por utilizar Javascript nativo para obtener su elemento.

 

Use el inyector angular

Puede usar el siguiente código para obtener una referencia a $ compile si no tiene uno.

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

Resumen

La publicación original parecía suponer que tenías una referencia de comstackción $ a la mano. Obviamente es fácil cuando tienes la referencia, pero yo no, así que esta fue la respuesta para mí.

Una advertencia del código anterior

Si está utilizando un paquete asp.net/mvc con el escenario minify, tendrá problemas cuando se despliegue en modo de lanzamiento. El problema viene en forma de Error no detectado: [$ injector: unpr] causado por el error del minificador con el código angular de javascript.

Aquí está la manera de remediarlo :

Reemplace el fragmento de código prevous con la siguiente sobrecarga.

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

Esto causó mucho dolor para mí antes de reconstruirlo.

Adición a la respuesta de @ jwize

Debido a que angular.element(document).injector() estaba dando error injector is not defined Por lo tanto, he creado una función que puede ejecutar después de la llamada AJAX o cuando DOM se cambia con 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(); }]); } } 

úsalo pasando el selector de nuevo elemento. Me gusta esto

 compileAngularElement( '.user' ) ;