Подтвердить что ты не робот

AngularJS: прокрутите до конца элемента после применения изменений DOM

У меня есть простой список элементов. Я хочу иметь возможность прокручивать нижнюю часть элемента, отображающего элементы, когда я добавляю больше элементов. Я понял, что нет возможности подключиться к концу функции $apply(), так что может быть моим решением?

Вот пример jsfiddle, чтобы проиллюстрировать мою проблему. после добавления достаточного количества элементов элемент ul не прокручивается до нижнего...

4b9b3361

Ответ 1

Там есть очень удивительный angularjs-scroll-glue, который делает именно то, что вы хотите.

Все, что вам нужно сделать, это применить директиву scroll-glue к вашему элементу контейнера и получить именно то, что вы ищете.

Там также доступна демонстрация.

Ответ 2

Другим правильным решением для этого является использование $timeout. Используя значение тайм-аута 0, angular будет ждать, пока DOM будет отображаться перед вызовом функции, которую вы передаете, на $timeout. Таким образом, после добавления элемента в список вы можете использовать это, чтобы дождаться добавления нового элемента в DOM перед прокруткой вниз.

Как @Mark Coleman решение, это не потребует дополнительных внешних библиотек.

var myApp = angular.module('myApp', []);

function MyCtrl($scope, $timeout) {
  $scope.list = ["item 1", "item 2", "item 3", "item 4", "item 5"];
  $scope.add = function() {
    $scope.list.push("new item");
    $timeout(function() {
      var scroller = document.getElementById("autoscroll");
      scroller.scrollTop = scroller.scrollHeight;
    }, 0, false);
  }
}
ul {
  height: 150px;
  overflow: scroll;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="MyCtrl">
    <button ng-click="add()">Add</button>
    <ul id="autoscroll">
      <li ng-repeat="item in list">{{item}}</li>
    </ul>
  </div>
</div>

Ответ 3

Вы можете создать простую директиву, которая привязывает обработчик кликов, который каждый раз прокручивает <ul> до конца.

myApp.directive("scrollBottom", function(){
    return {
        link: function(scope, element, attr){
            var $id= $("#" + attr.scrollBottom);
            $(element).on("click", function(){
                $id.scrollTop($id[0].scrollHeight);
            });
        }
    }
});

пример на jsfiddle

Ответ 4

Простой рабочий пример (нет необходимости в плагинах или директивах)...

.controller('Controller', function($scope, $anchorScroll, $location, $timeout) {

  $scope.func = function(data) {

    // some data appending here...

    $timeout(function() {
      $location.hash('end');
      $anchorScroll();
    })
  }

})

Трюк, который сделал это для меня, заключался в завершении команды anchorScroll с помощью $timeout, таким образом область была разрешена и автоматически переместилась в элемент в конце страницы.

Ответ 6

Вы можете добиться этого, используя пользовательский каталог углов.

пример:

<ul style="overflow: auto; max-height: 160px;" id="promptAnswerBlock">

<li ng-repeat="obj in objectKist track by $index" on-finish-render="ngRepeatFinished">                                              

  app.directive('onFinishRender', function($timeout) {
    return {
        restrict : 'A',
        link : function(scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function() {
                    $('#promptAnswerBlock').scrollTop($('#promptAnswerBlock')[0].scrollHeight + 150);
                });
            }
          }
        }
    }); 

</li>