Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 9a045fb

Browse files
committed
feat(virtualRepeat): add md-start-index attribute.
1 parent 2ccbc9d commit 9a045fb

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/components/virtualRepeat/virtualRepeater.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ function VirtualRepeatContainerController($$rAF, $scope, $element, $attrs) {
111111
/** Called by the md-virtual-repeat inside of the container at startup. */
112112
VirtualRepeatContainerController.prototype.register = function(repeaterCtrl) {
113113
this.repeater = repeaterCtrl;
114-
114+
115115
angular.element(this.scroller)
116116
.on('scroll wheel touchmove touchend', angular.bind(this, this.handleScroll_));
117117
};
@@ -192,10 +192,17 @@ VirtualRepeatContainerController.prototype.getScrollOffset = function() {
192192
return this.scrollOffset;
193193
};
194194

195+
/**
196+
* Scrolls to a given scrollTop position.
197+
* @param {number} position
198+
*/
199+
VirtualRepeatContainerController.prototype.scrollTo = function(position) {
200+
this.scroller[this.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = position;
201+
this.handleScroll_();
202+
};
195203

196204
VirtualRepeatContainerController.prototype.resetScroll = function() {
197-
this.scroller[this.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = 0;
198-
this.handleScroll_();
205+
this.scrollTo(0);
199206
};
200207

201208

@@ -293,6 +300,13 @@ function VirtualRepeatController($scope, $element, $attrs, $browser, $document)
293300
// getComputedStyle?
294301
/** @type {number} Height/width of repeated elements. */
295302
this.itemSize = $scope.$eval($attrs.mdItemSize);
303+
304+
/** @type {boolean} Whether this is the first time that items are rendered. */
305+
this.isFirstRender = true;
306+
307+
/** @type {number} Most recently seen length of items. */
308+
this.itemsLength = 0;
309+
296310
/**
297311
* Presently rendered blocks by repeat index.
298312
* @type {Object<number, !VirtualRepeatController.Block}
@@ -371,6 +385,12 @@ VirtualRepeatController.prototype.getItemSize = function() {
371385
*/
372386
VirtualRepeatController.prototype.virtualRepeatUpdate_ = function(items, oldItems) {
373387
var itemsLength = items ? items.length : 0;
388+
var lengthChanged = false;
389+
390+
if (itemsLength !== this.itemsLength) {
391+
lengthChanged = true;
392+
this.itemsLength = itemsLength;
393+
}
374394

375395
// If the number of items shrank, scroll up to the top.
376396
if (this.items && itemsLength < this.items.length && this.container.getScrollOffset() !== 0) {
@@ -385,7 +405,16 @@ VirtualRepeatController.prototype.virtualRepeatUpdate_ = function(items, oldItem
385405
}
386406

387407
this.parentNode = this.$element[0].parentNode;
388-
this.container.setScrollSize(itemsLength * this.itemSize);
408+
409+
if (lengthChanged) {
410+
this.container.setScrollSize(itemsLength * this.itemSize);
411+
}
412+
413+
if (this.isFirstRender) {
414+
this.isFirstRender = false;
415+
var startIndex = this.$attrs.mdStartIndex ? this.$scope.$eval(this.$attrs.mdStartIndex) : 0;
416+
this.container.scrollTo(startIndex * this.itemSize);
417+
}
389418

390419
// Detach and pool any blocks that are no longer in the viewport.
391420
Object.keys(this.blocks).forEach(function(blockIndex) {

src/components/virtualRepeat/virtualRepeater.spec.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ describe('<md-virtual-repeat>', function() {
99
var REPEATER_HTML = ''+
1010
'<div md-virtual-repeat="i in items" ' +
1111
' md-item-size="10" ' +
12+
' md-start-index="startIndex" ' +
1213
' style="height: 10px; width: 10px; box-sizing: border-box;">' +
1314
' {{i}} {{$index}}' +
1415
'</div>';
@@ -28,6 +29,7 @@ describe('<md-virtual-repeat>', function() {
2829
$compile = _$compile_;
2930
$document = _$document_;
3031
scope = $rootScope.$new();
32+
scope.startIndex = 0;
3133
scroller = null;
3234
sizer = null;
3335
offsetter = null;
@@ -249,6 +251,16 @@ describe('<md-virtual-repeat>', function() {
249251
}
250252
});
251253

254+
it('should start at the given scroll position', function() {
255+
scope.startIndex = 10;
256+
scope.items = createItems(200);
257+
createRepeater();
258+
scope.$apply();
259+
$$rAF.flush();
260+
261+
expect(scroller[0].scrollTop).toBe(10 * ITEM_SIZE);
262+
});
263+
252264
/**
253265
* Facade to access transform properly even when jQuery is used;
254266
* since jQuery's css function is obtaining the computed style (not wanted)

0 commit comments

Comments
 (0)