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

Commit 4e579dd

Browse files
ernsheongkara
authored andcommitted
fix(virtualRepeat): fix datepicker scroll to wrong current date (#10537)
Fixes #10144
1 parent 5383f94 commit 4e579dd

File tree

3 files changed

+23
-17
lines changed

3 files changed

+23
-17
lines changed

src/components/datepicker/js/calendar.spec.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ describe('md-calendar', function() {
2626
if (activeViewController) {
2727
angular.element(activeViewController.calendarScroller).triggerHandler('scroll');
2828
}
29+
30+
// Need this to handle the nextTick when setting first scroll.
31+
$timeout.flush();
2932
}
3033

3134
/** Extracts text as an array (one element per cell) from a tr element. */

src/components/virtualRepeat/virtual-repeater.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ function VirtualRepeatController($scope, $element, $attrs, $browser, $document,
522522
this.$attrs = $attrs;
523523
this.$browser = $browser;
524524
this.$document = $document;
525+
this.$mdUtil = $mdUtil;
525526
this.$rootScope = $rootScope;
526527
this.$$rAF = $$rAF;
527528

@@ -761,16 +762,6 @@ VirtualRepeatController.prototype.virtualRepeatUpdate_ = function(items, oldItem
761762
this.container.setScrollSize(itemsLength * this.itemSize);
762763
}
763764

764-
var cleanupFirstRender = false, firstRenderStartIndex;
765-
if (this.isFirstRender) {
766-
cleanupFirstRender = true;
767-
this.isFirstRender = false;
768-
firstRenderStartIndex = this.$attrs.mdStartIndex ?
769-
this.$scope.$eval(this.$attrs.mdStartIndex) :
770-
this.container.topIndex;
771-
this.container.scrollToIndex(firstRenderStartIndex);
772-
}
773-
774765
// Detach and pool any blocks that are no longer in the viewport.
775766
Object.keys(this.blocks).forEach(function(blockIndex) {
776767
var index = parseInt(blockIndex, 10);
@@ -822,16 +813,25 @@ VirtualRepeatController.prototype.virtualRepeatUpdate_ = function(items, oldItem
822813
this.blocks[maxIndex] && this.blocks[maxIndex].element[0].nextSibling);
823814
}
824815

825-
// DOM manipulation may have altered scroll, so scroll again
826-
if (cleanupFirstRender) {
827-
this.container.scrollToIndex(firstRenderStartIndex);
828-
}
829816
// Restore $$checkUrlChange.
830817
this.$browser.$$checkUrlChange = this.browserCheckUrlChange;
831818

832819
this.startIndex = this.newStartIndex;
833820
this.endIndex = this.newEndIndex;
834821

822+
if (this.isFirstRender) {
823+
this.isFirstRender = false;
824+
var firstRenderStartIndex = this.$attrs.mdStartIndex ?
825+
this.$scope.$eval(this.$attrs.mdStartIndex) :
826+
this.container.topIndex;
827+
828+
// The first call to virtualRepeatUpdate_ may not be when the virtual repeater is ready.
829+
// Introduce a slight delay so that the update happens when it is actually ready.
830+
this.$mdUtil.nextTick(function() {
831+
this.container.scrollToIndex(firstRenderStartIndex);
832+
}.bind(this));
833+
}
834+
835835
this.isVirtualRepeatUpdating_ = false;
836836
};
837837

src/components/virtualRepeat/virtual-repeater.spec.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ describe('<md-virtual-repeat>', function() {
2727
' style="height: 10px; width: 10px; box-sizing: border-box;">' +
2828
' {{i}} {{$index}}' +
2929
'</div>';
30-
var container, repeater, component, $$rAF, $compile, $document, $mdUtil, $window, scope,
31-
scroller, sizer, offsetter;
30+
var container, repeater, component, $$rAF, $compile, $document, $mdUtil, $timeout,
31+
$window, scope, scroller, sizer, offsetter;
3232

3333
var NUM_ITEMS = 110,
3434
VERTICAL_PX = 100,
3535
HORIZONTAL_PX = 150,
3636
ITEM_SIZE = 10;
3737

3838
beforeEach(inject(function(
39-
_$$rAF_, _$compile_, _$document_, _$mdUtil_, $rootScope, _$window_, _$material_) {
39+
_$$rAF_, _$compile_, _$document_, _$mdUtil_, $rootScope, _$timeout_, _$window_, _$material_) {
4040
repeater = angular.element(REPEATER_HTML);
4141
container = angular.element(CONTAINER_HTML).append(repeater);
4242
component = null;
@@ -45,6 +45,7 @@ describe('<md-virtual-repeat>', function() {
4545
$mdUtil = _$mdUtil_;
4646
$compile = _$compile_;
4747
$document = _$document_;
48+
$timeout = _$timeout_;
4849
$window = _$window_;
4950
scope = $rootScope.$new();
5051
scope.startIndex = 0;
@@ -374,6 +375,7 @@ describe('<md-virtual-repeat>', function() {
374375
scope.items = createItems(200);
375376
createRepeater();
376377
scope.$apply();
378+
$timeout.flush();
377379
$$rAF.flush();
378380

379381
expect(scroller[0].scrollTop).toBe(10 * ITEM_SIZE);
@@ -597,6 +599,7 @@ describe('<md-virtual-repeat>', function() {
597599
scope.items = createItems(200);
598600
createRepeater();
599601
scope.$apply();
602+
$timeout.flush();
600603

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

0 commit comments

Comments
 (0)