Skip to content

Commit

Permalink
fix(virtualRepeat): Virtual repeat starting off empty angular#3807
Browse files Browse the repository at this point in the history
Closes angular#4112. Fixes angular#3807.
  • Loading branch information
kseamon authored and kennethcachia committed Sep 23, 2015
1 parent 0a4ffae commit 4b47d45
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/components/virtualRepeat/virtualRepeater.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,12 @@ function VirtualRepeatController($scope, $element, $attrs, $browser, $document,
/** @type {number} Most recently seen length of items. */
this.itemsLength = 0;

/**
* @type {!Function} Unwatch callback for item size (when md-items-size is
* not specified), or angular.noop otherwise.
*/
this.unwatchItemSize_ = angular.noop;

/**
* Presently rendered blocks by repeat index.
* @type {Object<number, !VirtualRepeatController.Block}
Expand Down Expand Up @@ -407,6 +413,11 @@ VirtualRepeatController.prototype.link_ =

/** @private Attempts to set itemSize by measuring a repeated element in the dom */
VirtualRepeatController.prototype.readItemSize_ = function() {
if (this.itemSize) {
// itemSize was successfully read in a different asynchronous call.
return;
}

this.items = this.repeatListExpression(this.$scope);
this.parentNode = this.$element[0].parentNode;
var block = this.getBlock_(0);
Expand All @@ -430,14 +441,22 @@ VirtualRepeatController.prototype.readItemSize_ = function() {
VirtualRepeatController.prototype.containerUpdated = function() {
// If itemSize is unknown, attempt to measure it.
if (!this.itemSize) {
this.$$rAF(angular.bind(this, this.readItemSize_));
this.unwatchItemSize_ = this.$scope.$watch(
this.repeatListExpression,
angular.bind(this, function(items) {
if (items && items.length) {
this.$$rAF(angular.bind(this, this.readItemSize_));
}
}));
this.$scope.$digest();

return;
} else if (!this.sized) {
this.items = this.repeatListExpression(this.$scope);
}

if (!this.sized) {
this.unwatchItemSize_();
this.sized = true;
this.$scope.$watchCollection(this.repeatListExpression,
angular.bind(this, this.virtualRepeatUpdate_));
Expand Down
16 changes: 16 additions & 0 deletions src/components/virtualRepeat/virtualRepeater.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,22 @@ describe('<md-virtual-repeat>', function() {
expect(container[0].offsetWidth).toBe(2 * ITEM_SIZE);
});

it('should measure item size after data has loaded (no md-item-size)', function() {
repeater.removeAttr('md-item-size');
createRepeater();
scope.$apply();
$$rAF.flush();

expect(getRepeated().length).toBe(0);

scope.items = createItems(NUM_ITEMS);
scope.$apply();
$$rAF.flush();

var numItemRenderers = VERTICAL_PX / ITEM_SIZE + VirtualRepeatController.NUM_EXTRA;
expect(getRepeated().length).toBe(numItemRenderers);
});

/**
* 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 4b47d45

Please sign in to comment.