Je travaille sur une application Ajax utilisant jQuery et AngularJS.
Lorsque je mets à jour le contenu (qui contient des liaisons AngularJS) d'un div à l'aide de la fonction html
de jQuery, les liaisons AngularJS ne fonctionnent pas.
Voici le code de ce que j'essaie de faire:
$(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>
J'ai du contenu dynamique dans une div portant l'ID #dynamicContent
, et j'ai un bouton d'actualisation qui permet de mettre à jour le contenu de cette div lorsque vous cliquez sur l'actualisation. L'incrément fonctionne comme prévu si je n'actualise pas le contenu, mais après l'actualisation, la liaison AngularJS cesse de fonctionner.
Cela n’est peut-être pas valable dans AngularJS, mais j’ai initialement créé une application avec jQuery et commencé à utiliser AngularJS plus tard, de sorte que je ne peux pas tout migrer vers AngularJS. Toute aide pour que cela fonctionne dans AngularJS est grandement appréciée.
Vous devez appeler $compile
sur la chaîne HTML avant de l'insérer dans le DOM afin que angular ait la possibilité d'effectuer la liaison).
Dans votre violon, cela ressemblerait à quelque chose comme ça.
$("#dynamicContent").html(
$compile(
"<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>"
)(scope)
);
Évidemment, $compile
doit être injecté dans votre contrôleur pour que cela fonctionne.
Plus d'informations dans le $compile
documentation .
ne autre solution au cas où vous ne contrôleriez pas le contenu dynamique
Cela fonctionne si vous n'avez pas chargé votre élément via une directive (c'est-à-dire comme dans l'exemple du jsfiddles commenté).
résumez votre conten
Enveloppez votre contenu dans un div afin que vous puissiez le sélectionner si vous utilisez JQuery. Vous pouvez également choisir d’utiliser le javascript natif pour obtenir votre élément.
<div class="selector">
<grid-filter columnname="LastNameFirstName" gridname="HomeGrid"></grid-filter>
</div>
tilisez Angular Injector
Vous pouvez utiliser le code suivant pour obtenir une référence à $ compile si vous n'en avez pas.
$(".selector").each(function () {
var content = $(this);
angular.element(document).injector().invoke(function($compile) {
var scope = angular.element(content).scope();
$compile(content)(scope);
});
});
Résumé
Le message original semblait supposer que vous aviez une référence $ compile à portée de main. C'est évidemment facile lorsque vous avez la référence, mais je ne l'avais pas alors c'était la réponse pour moi.
ne mise en garde du code précédent
Si vous utilisez un bundle asp.net/mvc avec un scénario minify, vous aurez des problèmes lorsque vous déployez en mode de publication. Le problème se présente sous la forme d'une erreur non capturée: [$ injector: UNN], qui est causée par le minificateur qui manipule le angular code javascript.
Voici le moyen d'y remédier:
Remplacez l'extrait de code précédent par la surcharge suivante.
...
angular.element(document).injector().invoke(
[
"$compile", function($compile) {
var scope = angular.element(content).scope();
$compile(content)(scope);
}
]);
...
Cela m'a causé beaucoup de chagrin avant de le reconstituer.
Ajout à la réponse de @ jwize
Parce que angular.element(document).injector()
donnait l'erreur injector is not defined
Ainsi, j'ai créé une fonction que vous pouvez exécuter après l'appel AJAX ou lorsque DOM est modifié à l'aide de 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();
}]);
}
}
utilisez-le en passant juste le sélecteur de nouvel élément. comme ça
compileAngularElement( '.user' ) ;