List of objects is rendered using ng-repeat
. Suppose that this list is very long and user is scrolling to the bottom to see some objects.
While user is observing an object, a new item is added to the top of the list. This causes the observed object to change its position, i.e. the user suddenly sees something else at the same place of the observed object.
How would you go about keeping the observed object at the same place when new items are added?
You could defer adding the items until the user scrolls the top of the list into view. There is no point rendering the items before.
It could look like this (perhaps with an added animation).
Below is an improvement to Arthur's version that prevents scrolling regardless if the added item is added above or below the scroll: JS Bin
You could scroll by the amount of the height of the added elements
I am using a bad practice of accessing the DOM from the controller. A more modular approach would be to create a directive which will handle all cases and change the scroll position after the view is updated.
Demo at http://jsbin.com/zofofapo/8/edit
Alternatively, for the case where the items are not equally high, you could see how much scroll is left before the insertion, and re-set it after the insertion
Demo at http://jsbin.com/zofofapo/9/edit
You can solve this problem with ng-animate:
Just assign the css-class .keep-scroll to your repeated elements, like this:
The FaceBook Way: Everyone is suggesting this, here is a pseudo-implementation:
MYEXAMPLE
As new objects are added, pop them into a "More Queue".
MessageHandlerController will have at least 2 arrays (we should treat as queue's b/c we'll pop from bottom, up.
As your Signal R/Service Bus populates your
WaitingQueue
, yourng-if
renders increases in size and your$scope.SizeOfWaitingQueue=SizeOfWaitingQueue()
. This re-assigning process should happen every iteration so you don't have to dirty check your More size RepoIt maybe solved quite elegantly, by using
scrollTop
property ofdiv
. I used two directives - one handles scroll position of the wrapper element, the other register new elements. Give me a shout if anything unclear.DEMO
JS:
HTML: