Как зарегистрировать событие, когда angularjs завершает рендеринг интерфейса

Например

function SomeCtrl($scope) {
 $scope.list = [...]

 $scope.click = function() {
 var newdata = $someservice.get()
 angular.forEach(newdata, function(v){
 $scope.list.push(v) 
 })
 //???
 }
}

HTML:

<div id="main">
 <div ng-repeat="row in list">
 ...
 </div>
</div>

Мой вопрос заключается в том, когда я добавляю данные в $scope.list, как я могу получить уведомление, пока данные обновляются в пользовательском интерфейсе, потому что я хочу, чтобы основной div всегда прокручивался вниз?

2 ответа

попробуй это

var module = angular.module('testApp', [])
 .directive('onFinishRender', function ($timeout) {
 return {
 restrict: 'A',
 link: function (scope, element, attr) {
 if (scope.$last === true) {
 $timeout(function () {
 scope.$emit('ngRepeatFinished');
 });
 }
 }
 }
});

Обратите внимание, что я не использовал.ready(), а скорее завернул его в $ timeout. $ timeout гарантирует, что он будет выполнен, когда ng-повторяющиеся элементы имеют ДЕЙСТВИТЕЛЬНО закончили рендеринг (потому что $ timeout будет выполняться в конце текущего цикла дайджеста - и он также вызовет $ apply внутри, в отличие от setTimeout). Поэтому, после завершения ng-repeat, мы используем $ emit, чтобы излучать событие во внешние области (родственные и родительские области).

И затем в вашем контроллере вы можете поймать его с помощью $ on:

$scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
 //you also get the actual event object
 //do stuff, execute functions -- whatever...
});


Ravi опубликовал отличную директиву для прослушивания рендеринга ngRepeat. Кроме того, я бы создал другую директиву для содержимого автопрокрутки при обновлении. Тогда весь код будет примерно таким:

// +1 to Ravi
app.directive('onFinishRender', function($timeout) {
 return {
 link: function (scope, element, attr) {
 if (scope.$last === true) {
 $timeout(function () {
 scope.$emit('ngRepeatFinished');
 });
 }
 }
 }
});

// Scroll content on every ngRepeatFinished event
app.directive('autoScroll', function() {
 return {
 link: function(scope, element) {
 scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
 element[0].scrollTop = element[0].scrollHeight;
 });
 }
 };
});

Используйте его в HTML:

<div id="main" auto-scroll="">
 <div ng-repeat="row in list" on-finish-render="">
 <p>{{row}}</p>
 </div>
</div>

Демо: http://jsfiddle.net/C5xKv/

licensed under cc by-sa 3.0 with attribution.