web-dev-qa-db-fra.com

Faites défiler vers le haut de div dans AngularJS?

J'utilise AngularJS pour une petite application Web et j'ai rencontré un problème. J'utilise ng-repeat pour remplir une liste à l'intérieur d'un div. La div a une hauteur fixe et est définie sur overflow-y: auto, ce qui signifie qu'une barre de défilement apparaît lorsque la liste est trop longue pour la div. Mon problème est que, lorsque la liste est redessinée, c’est-à-dire que les modifications de répétition de sauvegarde de données sont modifiées, la barre de défilement ne se réinitialise pas en haut de la div. Au lieu de cela, il reste à la position de la barre de défilement avant le changement ng-repeat. C'est une très mauvaise expérience utilisateur. J'ai essayé ce qui suit sans aucun succès:

<div id="myList">
  <ul>
    <li ng-repeat="item in items">{{item}}</li>
  </ul>
</div>

<a ng-click="switchItems()">Switch</a>

<script>
function MyApp($scope) {
  $scope.switchItems = function() {
    $('#myList').scrollTop();
    $scope.items = [1, 2, 3, 4]; // new items
  };
}
</script>
37
Max

J'ai le même problème et je le résous généralement avec la directive générique suivante. Il écoute un événement donné et chaque fois que cet événement se produit, il remet l'élément en arrière jusqu'à y = 0. Tout ce que vous avez à faire, c'est $broadcast l'événement dans votre contrôleur lorsque votre liste change.

angular.module("ui.scrollToTopWhen", [])
.directive("scrollToTopWhen", function ($timeout) {
  function link (scope, element, attrs) {
    scope.$on(attrs.scrollToTopWhen, function () {
      $timeout(function () {
        angular.element(element)[0].scrollTop = 0;
      });
    });
  }
});

Usage:

// Controller
$scope.items = [...];
$scope.$broadcast("items_changed")

// Template
<div id="myList" scroll-to-top-when="items_changed">
54
Elise

Je voudrais simplement ajouter une directive qui surveille le contenu de la DIV. Il ferait ensuite défiler vers le haut chaque fois que le contenu change! Cette solution ne nécessite pas de traitement d'événement (ce qui, à mon avis, n'est pas nécessaire ici).

mod.directive('scrollToTop', function(){
    return {
        restrict: 'A',
        link: function postLink(scope, elem, attrs) {
            scope.$watch(attrs.scrollToTop, function() {
                elem[0].scrollTop = 0;
            });
        }
    };
});

Le balisage HTML utiliserait alors la directive pour déclencher le défilement, ainsi:

<div class='myList' data-scroll-to-top='data.items.length'>
  <ul>
    <li data-ng-repeat='item in data.items'>{{item}}</li>
  </ul>
</div>

Au fur et à mesure que vous ajoutez des éléments à la liste, la DIV fera défiler vers le haut! Voici un jsFiddle avec un code de travail: http://jsfiddle.net/pkgbtw59/89/

19
Bonneville

J'ai rencontré le même problème avec le défilement du corps de la table. Je l'ai résolu de la manière suivante.

Voici mon exemple html.

<table id="rateplanmapping-scroll">
    <thead>
       <th></th>....
    </thead>
    <tbody >
        <tr ng-repeat="data in datas"> //this is the data
            <td></td>.....
        </tr>
    </tbody>
</table>

Voici le angular angulaire pour faire défiler vers le haut

<script>

  angular.element("#rateplanmapping-scroll tbody")[0].scrollTop=0; 

</script>

J'espère que ça aide.
Vous pouvez mettre ce script dans la fonction requise pour qu’il se déclenche automatiquement lorsque des événements particuliers se produisent. Ou peut être attaché à l'événement aussi.

Pour l'élément div, cela peut être fait de la manière suivante

http://plnkr.co/edit/0B4zrFTho6GYuPAS0S1A?p=preview

Merci.

4
RIYAJ KHAN

Vous pouvez également utiliser $ anchorScroll selon le docs

// set the location.hash to the id of
// the element you wish to scroll to.
$location.hash('bottom');

// call $anchorScroll()
$anchorScroll();

Vous devriez envelopper ceci dans un délai d'attente de $:

$timeout(function() {
  $location.hash('myList');
  $anchorScroll();
})
4
Chris Ritchie