2013-06-25 11 views
34

Ich habe eine einfache Liste von Elementen. Ich möchte in der Lage sein, bis zum Ende des Elements zu blättern, das die Elemente anzeigt, wenn ich weitere Elemente hinzufüge. Ich habe verstanden, dass es keine Möglichkeit gibt, bis zum Ende der $apply() Funktion zu haken, was könnte meine Lösung sein?AngularJS: Scroll bis zum Ende des Elements nach dem Anwenden von DOM-Änderungen

Hier ist ein jsfiddle, um mein Problem zu veranschaulichen. Nach dem Hinzufügen von genügend Elementen scrollt das ul-Element nicht nach unten ...

Antwort

69

ist da noch die sehr geile angularjs-scroll-glue zur Verfügung, die genau das tut, was Sie wollen.

Sie müssen lediglich die Anweisung scroll-glue auf Ihr Containerelement anwenden, und Sie erhalten genau das, wonach Sie suchen.

Es ist auch eine demo verfügbar.

+3

das ist eine gute Lösung, aber ich möchte nicht viele externe lib verwenden. Weißt du, wie man es programmiert? –

+3

@JohnNguyen: Nun, es ist [Open Source] (https://github.com/Luegg/angularjs-scroll-glue/blob/master/src/scrollglue.js). –

+2

lohnt sich die Abhängigkeit .. diese Art von Prozess der Uhr für das DOM und dann weiter mit der Rolle erzeugt unnötigen Code .. in diesem Fall passt diese Bibliothek perfekt .. –

5

Sie könnten eine einfache Direktive erstellen, die einen Click-Handler bindet, der die <ul> jedes Mal nach unten scrollt.

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

example on jsfiddle

+0

Dank Mark es hat mir geholfen. Dies kann etwas besser mit $ Timeout-Dienst aktualisiert werden. Ich habe in jsfiddle http://jsfiddle.net/w5Vgw/99/ aktualisiert. – Dilip

+0

Während dies nette kleine Direktive ist, löst es das Problem nicht. Es scrollt sofort, ohne darauf zu warten, dass ein neues Element zu DOM hinzugefügt wird. – zendu

23

Eine weitere gültige Lösung dieses Problems ist $timeout verwenden. Mit einem Zeitüberschreitungswert von 0 wartet eckig, bis das DOM gerendert wird, bevor die Funktion aufgerufen wird, die Sie an $timeout übergeben haben. Nachdem Sie der Liste ein Element hinzugefügt haben, können Sie damit warten, dass das neue Element zum DOM hinzugefügt wird, bevor Sie nach unten scrollen.

Wie @Mark Colemansolution, erfordert dies keine zusätzlichen externen Bibliotheken.

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>

+0

Oder Sie können einfach Ihre Sammlung in den Link und dann zu dem Element scrollen. Außerdem haben Sie einfachen Zugriff auf Elemente in Verbindung ... – Void

+0

Diese Lösung macht den Controller auf das DOM aufmerksam und manipuliert es direkt. Wäre das nicht unwinklig? Lieber diesen Teil in einer Direktive tun? – tom

5

Ein einfaches Ausführungsbeispiel (keine Notwendigkeit für Plugins oder Richtlinien) ...

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

    $scope.func = function(data) { 

    // some data appending here... 

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

}) 

Der Trick, der es tat, war für mich mit $timeout den anchorScroll Befehl Einwickeln, Auf diese Weise wurde der Bereich aufgelöst und automatisch zu einem Element am Ende der Seite verschoben.

+0

Vielen Dank für die gute und einfache Lösung. Es funktioniert und hilft mir) –

+0

Einfach, aber mit der Einschränkung, dass es die URL mit dem Hash-Wert ändert. –

-1

Sie können dies mit dem benutzerdefinierten Verzeichnis angularjs erreichen.

Beispiel:

<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> 
+0

ng-repeat = "Attributwert in attribute.attributeValueList track by $ index" on-finish-render = "ngRepeatFinished" –

+0

Bitte formatieren Sie Ihren Code – adao7000

Verwandte Themen