Skip to content

Commit 4b47d45

Browse files
kseamonkennethcachia
authored andcommitted
fix(virtualRepeat): Virtual repeat starting off empty angular#3807
Closes angular#4112. Fixes angular#3807.
1 parent 0a4ffae commit 4b47d45

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/components/virtualRepeat/virtualRepeater.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,12 @@ function VirtualRepeatController($scope, $element, $attrs, $browser, $document,
365365
/** @type {number} Most recently seen length of items. */
366366
this.itemsLength = 0;
367367

368+
/**
369+
* @type {!Function} Unwatch callback for item size (when md-items-size is
370+
* not specified), or angular.noop otherwise.
371+
*/
372+
this.unwatchItemSize_ = angular.noop;
373+
368374
/**
369375
* Presently rendered blocks by repeat index.
370376
* @type {Object<number, !VirtualRepeatController.Block}
@@ -407,6 +413,11 @@ VirtualRepeatController.prototype.link_ =
407413

408414
/** @private Attempts to set itemSize by measuring a repeated element in the dom */
409415
VirtualRepeatController.prototype.readItemSize_ = function() {
416+
if (this.itemSize) {
417+
// itemSize was successfully read in a different asynchronous call.
418+
return;
419+
}
420+
410421
this.items = this.repeatListExpression(this.$scope);
411422
this.parentNode = this.$element[0].parentNode;
412423
var block = this.getBlock_(0);
@@ -430,14 +441,22 @@ VirtualRepeatController.prototype.readItemSize_ = function() {
430441
VirtualRepeatController.prototype.containerUpdated = function() {
431442
// If itemSize is unknown, attempt to measure it.
432443
if (!this.itemSize) {
433-
this.$$rAF(angular.bind(this, this.readItemSize_));
444+
this.unwatchItemSize_ = this.$scope.$watch(
445+
this.repeatListExpression,
446+
angular.bind(this, function(items) {
447+
if (items && items.length) {
448+
this.$$rAF(angular.bind(this, this.readItemSize_));
449+
}
450+
}));
451+
this.$scope.$digest();
434452

435453
return;
436454
} else if (!this.sized) {
437455
this.items = this.repeatListExpression(this.$scope);
438456
}
439457

440458
if (!this.sized) {
459+
this.unwatchItemSize_();
441460
this.sized = true;
442461
this.$scope.$watchCollection(this.repeatListExpression,
443462
angular.bind(this, this.virtualRepeatUpdate_));

src/components/virtualRepeat/virtualRepeater.spec.js

+16
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,22 @@ describe('<md-virtual-repeat>', function() {
390390
expect(container[0].offsetWidth).toBe(2 * ITEM_SIZE);
391391
});
392392

393+
it('should measure item size after data has loaded (no md-item-size)', function() {
394+
repeater.removeAttr('md-item-size');
395+
createRepeater();
396+
scope.$apply();
397+
$$rAF.flush();
398+
399+
expect(getRepeated().length).toBe(0);
400+
401+
scope.items = createItems(NUM_ITEMS);
402+
scope.$apply();
403+
$$rAF.flush();
404+
405+
var numItemRenderers = VERTICAL_PX / ITEM_SIZE + VirtualRepeatController.NUM_EXTRA;
406+
expect(getRepeated().length).toBe(numItemRenderers);
407+
});
408+
393409
/**
394410
* Facade to access transform properly even when jQuery is used;
395411
* since jQuery's css function is obtaining the computed style (not wanted)

0 commit comments

Comments
 (0)