2

I've been trying to find out how to execute some view-specific javascript code when the model has changed. In the example below, whenever you click the "Say"-button, a new entry will be added to the model, updating the entries-list. The stylesheet limits the entries-list's height to about five entries.

What is the correct way to call something like scrollLastChatEntryElementIntoView();? I know how to scroll elements into view, but I can't seem to find any info on how and when I should do this in response to the view being updated? Where am I supposed to declare the script, and when am I supposed to call it?

<div class="chat">
   <ol class="entries">
      <li class="entry" ng-repeat="entry in chat.entries">
         <label>{{entry.sender}}</label> {{entry.text}}
      </li>
   </ol>
   <form class="newEntry" ng-submit="chat.newEntry.submit()">
      <input class="text" ng-model="chat.newEntry.text" placeholder="Type to chat"/>
      <span class="button submit" ng-click="chat.newEntry.submit()">Say</span>
   </form>
</div>

1 Answer 1

3

I had a similar situation recently and the way I did it was to create a "auto-scrolling" directive that is listening for the 'DOMSubtreeModified' event on the list element and automatically scrolls down when a new element is added to it.

app.directive('autoScrolling', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {

            var el = angular.element(element);

            scope.scrollDown = function(evt) {
                // scroll down:
                el.scrollTop(el.prop('scrollHeight'));
            };

            scope.scrollDown();
            // each time the DOM element of the list changes, 
            // make sure we are scrolled all the way down...
            element.bind('DOMSubtreeModified', scope.scrollDown);
        }
    };  
});

and then on your list element

<ol auto-scrolling>...

plnkr demo here

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you Sebastien. Your solution perfectly solves this particular problem.
+1. FYI, in the link function, element is already a wrapped jQuery element, so you don't have to re-wrap it as an angular element. In other words, you can use element everywhere in the link function -- no need for variable el.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.