Как запустить метод $scope.myWork()
после шаблона рендеринга? Я хочу установить $scope.value
, и после этого мне нужно что-то изменить с помощью JQuery (например, в DOM содержимого шаблона). $scope.$watch('value', function (){....})
работает "до" рендеринга (DOM шаблона еще недоступен). Спасибо.
AngularJS: обратный вызов после рендера (работа с DOM после рендера)
Ответ 1
Создайте directive, который запускает ваш код в функции ссылки. Функция ссылки вызывается после создания шаблона.
Чтобы получить представление, см. ng-click.
Ответ 2
Я использую terminal
и transclude
в директиве атрибута для вызова метода с областью действия после обновления модели и представления (в моем случае для изменения размера iframe после $Resource.query):
.directive('postRender', [ '$timeout', function($timeout) {
var def = {
restrict : 'A',
terminal : true,
transclude : true,
link : function(scope, element, attrs) {
$timeout(scope.resize, 0); //Calling a scoped method
}
};
return def;
}])
Таймаут $- черная магия. Должно быть возможно объявить JS-метод как значение атрибута, а $проанализировать его.
Поэтому я использую его в ng-repeat
(в моем случае дерево рекурсивно рекурсивно):
<div post-render ng-repeat="r in regions | orderBy:'name'" ng-include="'tree_region_renderer.html'">
Ответ 3
У меня также была эта проблема, другие решения не работали хорошо для меня, и это казалось тем, что, должно быть, решил решить. Быстрый анализ Скриптов клиентской стороны-протокатора показывает, что он использует angular.getTestability(element)
для того, чтобы знать, когда действительно запускать тесты. Метод ожидает, пока не будут ожидающие ожидания или http-запросы, а затем запустит ваш обратный вызов. Здесь моя директива:
export function afterRender ($timeout) {
"ngInject";
return {
restrict: 'A',
terminal: true,
link: function (scope, element, attrs) {
angular.getTestability(element).whenStable(function() {
console.log('[rendered]');
});
}
};
}
Ответ 4
Ответ Jens выше будет работать, но обратите внимание, что в новых версиях AngularJS (например, 1.2.3) вы не можете иметь эту директиву postRender в сочетании с ng-repeat в качестве атрибутов одного и того же тега, поскольку оба они переключили: true. В этом случае вы либо должны удалить transclude, либо иметь отдельный тег с атрибутом директивы postRender.
Также имейте в виду приоритет атрибутов при использовании терминала: true, так как вы можете получить неэффективный атрибут из-за более высокого приоритета в одном и том же теге.
Ответ 5
Я нашел эту страницу при поиске способа профилирования DOM. Я нашел очень простое решение, которое работает для моего использования.
Прикрепите обработчик ng-init к элементу DOM и в функции обработчика, используйте $timeout для выполнения выполнения. Пример:
HTML:
<div ng-init="foo()">
JS:
$scope.foo = function() {
$timeout(function() {
// This code runs after the DOM renders
});
});