AngularJS + JQuery: come ottenere contenuti dinamici lavorando in angularjs

Sto lavorando a un’app Ajax utilizzando sia jQuery che AngularJS.

Quando aggiorno il contenuto (che contiene i collegamenti AngularJS) di un div utilizzando la funzione html di jQuery, i collegamenti AngularJS non funzionano.

Di seguito è riportato il codice di ciò che sto cercando di fare:

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

Ho un contenuto dinamico all’interno di un div con ID #dynamicContent e ho un pulsante di aggiornamento che aggiornerebbe i contenuti di questo div quando si fa clic su Aggiorna. L’incremento funziona come previsto se non aggiorno il contenuto, ma dopo l’aggiornamento, l’associazione AngularJS smette di funzionare.

Questo potrebbe non essere valido in AngularJS, ma inizialmente ho creato un’applicazione con jQuery e ho iniziato ad utilizzare AngularJS in seguito, quindi non posso eseguire la migrazione di tutto ad AngularJS. Ogni aiuto per ottenere questo lavoro in AngularJS è molto apprezzato.

Devi chiamare $compile sulla stringa HTML prima di inserirlo nel DOM in modo che l’angular abbia la possibilità di eseguire l’associazione.

Nel tuo violino, sembrerebbe qualcosa del genere.

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

Ovviamente, $compile deve essere iniettato nel controller affinché funzioni.

Leggi di più nella documentazione $compile .

Un’altra soluzione nel caso in cui non hai il controllo sul contenuto dinamico

Questo funziona se non hai caricato il tuo elemento attraverso una direttiva (ad esempio nell’esempio nei jsfiddles commentati).

Racchiudi il tuo contenuto

Avvolgi il contenuto in un div in modo da poterlo selezionare se usi JQuery . Si sceglie anche di utilizzare javascript nativo per ottenere il tuo elemento.

 

Utilizzare l’iniettore angular

Puoi usare il seguente codice per ottenere un riferimento a $ compilare se non ne hai uno.

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

Sommario

Il post originale sembrava presumere che avessi a portata di mano un riferimento $ compilato. Ovviamente è facile quando hai il riferimento, ma non l’ho fatto, quindi questa era la risposta per me.

Un avvertimento del codice precedente

Se si utilizza un bundle asp.net/mvc con lo scenario minify, si verificherà un problema durante la distribuzione in modalità di rilascio. Il problema si presenta sotto forma di Unchaught Error: [$ injector: unpr] che è causato dal minificatore che ha problemi con il codice angular di javascript.

Ecco come risolverlo :

Sostituisci lo snippet di codice precedente con il seguente overload.

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

Questo ha causato molto dolore per me prima di metterlo insieme.

Aggiunta alla risposta di @ jwize

Perché angular.element(document).injector() stava dando errore injector is not defined Quindi, ho creato una funzione che puoi eseguire dopo una chiamata AJAX o quando il DOM viene modificato usando 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(); }]); } } 

usalo passando solo il nuovo selettore di elementi. come questo

 compileAngularElement( '.user' ) ;