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

Commit

Permalink
feat(virtualRepeat): add md-start-index attribute.
Browse files Browse the repository at this point in the history
  • Loading branch information
jelbourn committed Jun 26, 2015
1 parent 2ccbc9d commit 9a045fb
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
37 changes: 33 additions & 4 deletions src/components/virtualRepeat/virtualRepeater.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ function VirtualRepeatContainerController($$rAF, $scope, $element, $attrs) {
/** Called by the md-virtual-repeat inside of the container at startup. */
VirtualRepeatContainerController.prototype.register = function(repeaterCtrl) {
this.repeater = repeaterCtrl;

angular.element(this.scroller)
.on('scroll wheel touchmove touchend', angular.bind(this, this.handleScroll_));
};
Expand Down Expand Up @@ -192,10 +192,17 @@ VirtualRepeatContainerController.prototype.getScrollOffset = function() {
return this.scrollOffset;
};

/**
* Scrolls to a given scrollTop position.
* @param {number} position
*/
VirtualRepeatContainerController.prototype.scrollTo = function(position) {
this.scroller[this.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = position;
this.handleScroll_();
};

VirtualRepeatContainerController.prototype.resetScroll = function() {
this.scroller[this.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = 0;
this.handleScroll_();
this.scrollTo(0);
};


Expand Down Expand Up @@ -293,6 +300,13 @@ function VirtualRepeatController($scope, $element, $attrs, $browser, $document)
// getComputedStyle?
/** @type {number} Height/width of repeated elements. */
this.itemSize = $scope.$eval($attrs.mdItemSize);

/** @type {boolean} Whether this is the first time that items are rendered. */
this.isFirstRender = true;

/** @type {number} Most recently seen length of items. */
this.itemsLength = 0;

/**
* Presently rendered blocks by repeat index.
* @type {Object<number, !VirtualRepeatController.Block}
Expand Down Expand Up @@ -371,6 +385,12 @@ VirtualRepeatController.prototype.getItemSize = function() {
*/
VirtualRepeatController.prototype.virtualRepeatUpdate_ = function(items, oldItems) {
var itemsLength = items ? items.length : 0;
var lengthChanged = false;

if (itemsLength !== this.itemsLength) {
lengthChanged = true;
this.itemsLength = itemsLength;
}

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

this.parentNode = this.$element[0].parentNode;
this.container.setScrollSize(itemsLength * this.itemSize);

if (lengthChanged) {
this.container.setScrollSize(itemsLength * this.itemSize);
}

if (this.isFirstRender) {
this.isFirstRender = false;
var startIndex = this.$attrs.mdStartIndex ? this.$scope.$eval(this.$attrs.mdStartIndex) : 0;
this.container.scrollTo(startIndex * this.itemSize);
}

// Detach and pool any blocks that are no longer in the viewport.
Object.keys(this.blocks).forEach(function(blockIndex) {
Expand Down
12 changes: 12 additions & 0 deletions src/components/virtualRepeat/virtualRepeater.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ describe('<md-virtual-repeat>', function() {
var REPEATER_HTML = ''+
'<div md-virtual-repeat="i in items" ' +
' md-item-size="10" ' +
' md-start-index="startIndex" ' +
' style="height: 10px; width: 10px; box-sizing: border-box;">' +
' {{i}} {{$index}}' +
'</div>';
Expand All @@ -28,6 +29,7 @@ describe('<md-virtual-repeat>', function() {
$compile = _$compile_;
$document = _$document_;
scope = $rootScope.$new();
scope.startIndex = 0;
scroller = null;
sizer = null;
offsetter = null;
Expand Down Expand Up @@ -249,6 +251,16 @@ describe('<md-virtual-repeat>', function() {
}
});

it('should start at the given scroll position', function() {
scope.startIndex = 10;
scope.items = createItems(200);
createRepeater();
scope.$apply();
$$rAF.flush();

expect(scroller[0].scrollTop).toBe(10 * ITEM_SIZE);
});

/**
* Facade to access transform properly even when jQuery is used;
* since jQuery's css function is obtaining the computed style (not wanted)
Expand Down

0 comments on commit 9a045fb

Please sign in to comment.