Neil S
Neil S

Reputation: 2304

How can I manipulate the DOM after my directive's content has been loaded on the page?

I am writing my own chat interface, to help me better understand angularJs and socket.io.

My chat window is fixed, with overflow set to auto. I am using the following directive to manipulate the DOM to scroll, so that as each message is pushed onto the model array, it will be visible at the bottom of the window.

app.directive('plnkScroll', [function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
              angular.element(element)[0].scrollIntoView();
        }
    };
}]);

In theory, this works. However, if the message is long enough to take up more than one line, it does not scroll so that the entire line is clearly visible.

This is because the scrollIntoView method is being executed on the DOM while the angular expression has yet to be evaluated (in this case, {{item.text}})

Is it possible to execute this function after the Angular expression has been evaluated and the model data has been injected into the DOM?

here is my plunker, to help illustrate what I am doing.

p.s. using jQuery is not an option for me, I would like to do things "the angular way".

Upvotes: 1

Views: 1005

Answers (2)

jelinson
jelinson

Reputation: 845

To extend Kain's response, it actually works without specifying an arbitrary number of milliseconds for the timeout. Simply allowing a digest cycle to occur via the $timeout is sufficient. You can do this by omitting the second argument to the $timeout function, which defaults to zero.

Alternatively, if you wanted the scroll to occur based on a scope variable changing, you could specify an attribute to the directive to watch using scope.$watch and scroll when the watch fires.

Upvotes: 2

Kain
Kain

Reputation: 273

your can use $timeout excute your code after directive element append to parent.

app.directive('plnkScroll', ['$timeout',function ($timeout) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
              $timeout(function(){
                angular.element(element)[0].scrollIntoView();
              },50);
            }
        };
    }]);

Upvotes: 2

Related Questions