Я работаю над приложением Ajax, используя как jQuery, так и AngularJS.
Когда я обновляю содержимое (которое содержит привязки AngularJS) div с помощью html
функции jQuery , привязки AngularJS не работают.
Ниже приведен код того, что я пытаюсь сделать:
$(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>
У меня есть динамический контент внутри div с идентификатором #dynamicContent
, и у меня есть кнопка обновления, которая обновляет содержимое этого div при нажатии кнопки обновления. Приращение работает должным образом, если я не обновляю содержимое, но после обновления привязка AngularJS перестает работать.
Это может быть недопустимым в AngularJS, но я изначально создавал приложение с jQuery и позже начал использовать AngularJS, поэтому я не могу перенести все на AngularJS. Любая помощь в получении этой работы в AngularJS приветствуется.
Ответы:
Вам необходимо вызвать
$compile
строку HTML перед вставкой ее в DOM, чтобы angular получил возможность выполнить привязку.На вашей скрипке это будет выглядеть примерно так.
$("#dynamicContent").html( $compile( "<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>" )(scope) );
Очевидно,
$compile
чтобы это работало , его необходимо ввести в ваш контроллер.Подробнее читайте в
$compile
документации .источник
$scope.$apply()
вrefresh()
саму функцию, если это имеет смысл для вашей архитектуры: jsfiddle.net/nfreitas/8xkeh/1angular-1.0.1.min.js
в исходных примерах была 404. Вот обновленные рабочие версии примера @ ArtemAndreev-s: jsfiddle.net/pmorch/fABdD/186 и пример @NoahFreitasДругое решение, если у вас нет контроля над динамическим контентом
Это работает, если вы не загрузили свой элемент с помощью директивы (например, как в примере в закомментированных jsfiddles).
Завершите свой контент
Оберните свой контент в div, чтобы вы могли выбрать его, если вы используете JQuery . Вы также можете использовать собственный javascript для получения своего элемента.
<div class="selector"> <grid-filter columnname="LastNameFirstName" gridname="HomeGrid"></grid-filter> </div>
Использовать угловой инжектор
Вы можете использовать следующий код, чтобы получить ссылку на $ compile, если у вас ее нет.
$(".selector").each(function () { var content = $(this); angular.element(document).injector().invoke(function($compile) { var scope = angular.element(content).scope(); $compile(content)(scope); }); });
Резюме
Исходный пост, казалось, предполагал, что у вас есть справочник по компиляции $. Очевидно, что это легко, когда у вас есть ссылка, но у меня ее не было, поэтому это был ответ для меня.
Одно предостережение в отношении предыдущего кода
Если вы используете пакет asp.net/mvc со сценарием minify, у вас возникнут проблемы при развертывании в режиме выпуска. Проблема возникает в виде Неперехваченной ошибки: [$ injector: unpr], которая вызвана вмешательством минификатора в код javascript angular.
Вот способ исправить это :
Замените предыдущий фрагмент кода следующей перегрузкой.
... angular.element(document).injector().invoke( [ "$compile", function($compile) { var scope = angular.element(content).scope(); $compile(content)(scope); } ]); ...
Это вызвало у меня много горя, прежде чем я собрал все воедино.
источник
Дополнение к ответу @jwize
Потому что
angular.element(document).injector()
выдает ошибкуinjector is not defined
Итак, я создал функцию, которую вы можете запустить после вызова AJAX или когда DOM изменяется с помощью 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(); }]); } }
используйте его, передав только селектор нового элемента. как это
compileAngularElement( '.user' ) ;
источник
target
динамическим, взяв его из аргумента.