Estou trabalhando em um aplicativo Ajax usando jQuery e AngularJS.
Quando eu atualizo o conteúdo (que contém ligações AngularJS) de um div usando a html
função jQuery , as ligações AngularJS não funcionam.
A seguir está o código do que estou tentando fazer:
$(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>
Eu tenho conteúdo dinâmico dentro de um div com o ID #dynamicContent
e tenho um botão de atualização que atualizaria o conteúdo deste div quando atualizar fosse clicado. O incremento funciona conforme o esperado se eu não atualizar o conteúdo, mas depois de atualizar, a vinculação do AngularJS para de funcionar.
Isso pode não ser válido no AngularJS, mas inicialmente desenvolvi o aplicativo com jQuery e comecei a usar o AngularJS mais tarde, então não posso migrar tudo para o AngularJS. Qualquer ajuda para fazer isso funcionar no AngularJS é muito apreciada.
Respostas:
Você precisa chamar
$compile
a string HTML antes de inseri-la no DOM para que o angular tenha a chance de realizar a vinculação.Em seu violino, seria algo assim.
$("#dynamicContent").html( $compile( "<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>" )(scope) );
Obviamente,
$compile
deve ser injetado em seu controlador para que funcione.Leia mais na
$compile
documentação .fonte
$scope.$apply()
narefresh()
própria função se fizer sentido para sua arquitetura: jsfiddle.net/nfreitas/8xkeh/1angular-1.0.1.min.js
nos exemplos originais era 404. Aqui estão as versões de trabalho atualizadas do exemplo de @ ArtemAndreev-s: jsfiddle.net/pmorch/fABdD/186 e @NoahFreitas exemplo: jsfiddle.net/pmorch/8xkeh/43Outra solução caso você não tenha controle sobre o conteúdo dinâmico
Isso funciona se você não carregou seu elemento por meio de uma diretiva (ou seja, como no exemplo dos jsfiddles comentados).
Resuma o seu conteúdo
Envolva seu conteúdo em um div para que você possa selecioná-lo se estiver usando JQuery . Você também pode optar por usar javascript nativo para obter seu elemento.
<div class="selector"> <grid-filter columnname="LastNameFirstName" gridname="HomeGrid"></grid-filter> </div>
Use Injetor Angular
Você pode usar o código a seguir para obter uma referência para $ compile se não tiver um.
$(".selector").each(function () { var content = $(this); angular.element(document).injector().invoke(function($compile) { var scope = angular.element(content).scope(); $compile(content)(scope); }); });
Resumo
A postagem original parecia assumir que você tinha uma referência de $ compile à mão. É obviamente fácil quando você tem a referência, mas eu não tinha, então essa foi a resposta para mim.
Uma advertência do código anterior
Se você estiver usando um pacote asp.net/mvc com cenário minify, terá problemas ao implantar no modo de lançamento. O problema vem na forma de Erro não detectado: [$ injector: despr], que é causado pelo minificador que bagunça o código javascript angular.
Aqui está a maneira de remediar isso :
Substitua o trecho de código anterior com a seguinte sobrecarga.
... angular.element(document).injector().invoke( [ "$compile", function($compile) { var scope = angular.element(content).scope(); $compile(content)(scope); } ]); ...
Isso me causou muita dor antes de eu juntar as peças.
fonte
Adição à resposta de @jwize
Porque
angular.element(document).injector()
estava dando erroinjector is not defined
Então, eu criei uma função que você pode executar após a chamada AJAX ou quando o DOM é alterado 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(); }]); } }
use-o passando apenas pelo seletor de novo elemento. como isso
compileAngularElement( '.user' ) ;
fonte
target
dinâmico obtendo-o do argumento.