Сохранять положение прокрутки после добавления элементов в массив в ng-repeat

Отображение списка сообщений через ng-repeat, когда пользователь прокручивает вверх, старые сообщения загружаются через ion Refresh. Желательно, чтобы старые сообщения добавлялись над текущими сообщениями, а положение прокрутки текущих сообщений сохранялось.

HTML

<ion-content id="messageScroller" delegate-handle="userMessageScroll">

  <ion-refresher pulling-icon="ion-ios-arrow-thin-down" refreshing-text="loading messages" on-refresh="moreMessages()">
  </ion-refresher>

  <div ng-repeat="message in convo.messages">
    {{message.text}}
  </div>
</ion-content>

JS

$scope.moreMessages = function() {
  $scope.convo.messages = olderMessages().concat($scope.convo.messages)
}

Проблема в том, что когда вызывается больше сообщений, ионное содержимое прокручивается вверх (остается вверху?).

Как установить положение прокрутки, чтобы загрузка старых сообщений просто делала старые сообщения доступными при прокрутке вверх? Как в iMessage или других мессенджерах?


person werdnamai    schedule 04.02.2015    source источник


Ответы (2)


просмотрите $ionicScrollDelegate. Вы можете установить и получить положение прокрутки

person lyjackal    schedule 04.02.2015
comment
Это не идеально, так как $ionicScrollDelegate дает вам позицию прокрутки относительно верхней части контейнера прокрутки. Эта позиция всегда будет нулевой в ситуации, описанной выше. Возможно, вы сможете что-то сделать с якорями, но с этим тоже не повезло. - person werdnamai; 30.04.2015

Мне нужно было сделать то же самое в моем приложении и создать директиву, просто поместите директиву <load-more-at-top> перед <ion-list> внутри <ion-content>

Вот работающий плункер

myApp.directive('loadMoreAtTop', function($timeout) {
  return {
    restrict: 'E',
    scope: { onScroll: '&onScroll' },
    require: '^$ionicScroll',
    template: function() {
        return '<ion-refresher pulling-text="More..." on-refresh="growBounds()"></ion-refresher>';
    },
    link: function($scope, $element, attrs, scrollCtrl) {
      var scroller = scrollCtrl.$element[0];
      var lastHeight, 
          loading = false;
      $scope.growBounds = function growBounds() {
          loading = true;
          lastHeight = scroller.scrollHeight;
          console.log('lastHeight', lastHeight);
          $scope.onScroll();
      }

      function resetScrollPosition() {
          var height = scroller.scrollHeight;
          var difference = height - lastHeight;
          console.log('difference', difference, 'height', height, 'lastHeight', lastHeight);
          // reset the scroll based on previous height
          scrollCtrl.scrollTo(scrollCtrl.getScrollPosition().left, difference, true);
      }

      function finishGrowBounds() {
        if(loading) {
          $timeout(function() {
              loading = false;
              resetScrollPosition();
              $scope.$broadcast('scroll.refreshComplete');
          }, 0);
        }
      }

      $scope.$parent.$on('scroll.loaded', finishGrowBounds)
    }
  };
});
person lyjackal    schedule 01.05.2015
comment
Это решение отлично работает на iOS. Однако я получаю эту ошибку в консоли при использовании этого на платформе Android: Refresher must be immediate child of ion-content or ion-scroll Есть ли способ обойти это? - person Dragan Malinovic; 16.12.2016