fix(scrolling): leaking subscription if same element is registered multiple times (#13974)

If the `ScrollDispatcher.register` method is called twice in a row, the consumer will end up with a subscription that can't be cleaned up. These changes add an extra check to prevent the same scrollable from being re-registered.
This commit is contained in:
Kristiyan Kostadinov
2018-11-07 18:10:35 +00:00
committed by vivian-hu
parent 6fe84f317e
commit 20f89245f4
2 changed files with 21 additions and 4 deletions
@@ -112,6 +112,23 @@ describe('ScrollDispatcher', () => {
subscription.unsubscribe();
});
it('should not register the same scrollable twice', () => {
const scrollable = fixture.componentInstance.scrollable;
const scrollSpy = jasmine.createSpy('scroll spy');
const scrollSubscription = scroll.scrolled(0).subscribe(scrollSpy);
expect(scroll.scrollContainers.has(scrollable)).toBe(true);
scroll.register(scrollable);
scroll.deregister(scrollable);
dispatchFakeEvent(fixture.componentInstance.scrollingElement.nativeElement, 'scroll');
fixture.detectChanges();
expect(scrollSpy).not.toHaveBeenCalled();
scrollSubscription.unsubscribe();
});
});
describe('Nested scrollables', () => {
+4 -4
View File
@@ -52,10 +52,10 @@ export class ScrollDispatcher implements OnDestroy {
* @param scrollable Scrollable instance to be registered.
*/
register(scrollable: CdkScrollable): void {
const scrollSubscription = scrollable.elementScrolled()
.subscribe(() => this._scrolled.next(scrollable));
this.scrollContainers.set(scrollable, scrollSubscription);
if (!this.scrollContainers.has(scrollable)) {
this.scrollContainers.set(scrollable, scrollable.elementScrolled()
.subscribe(() => this._scrolled.next(scrollable)));
}
}
/**