diff --git a/src/components/progress-circle/progress-circle.spec.ts b/src/components/progress-circle/progress-circle.spec.ts index 11b6a25a5b0..9d83d11d0cb 100644 --- a/src/components/progress-circle/progress-circle.spec.ts +++ b/src/components/progress-circle/progress-circle.spec.ts @@ -74,6 +74,27 @@ describe('MdProgressCircular', () => { done(); }); }); + + it('should clean up the indeterminate animation when the element is destroyed', + (done: () => void) => { + let template = ``; + + builder + .overrideTemplate(TestApp, template) + .createAsync(TestApp) + .then((fixture) => { + fixture.detectChanges(); + let progressElement = getChildDebugElement(fixture.debugElement, 'md-progress-circle'); + expect(progressElement.componentInstance.interdeterminateInterval).toBeTruthy(); + + fixture.debugElement.componentInstance.isHidden = true; + fixture.detectChanges(); + expect(progressElement.componentInstance.interdeterminateInterval).toBeFalsy(); + done(); + }); + }); }); diff --git a/src/components/progress-circle/progress-circle.ts b/src/components/progress-circle/progress-circle.ts index 2ff87de24a9..6cb6d2676ec 100644 --- a/src/components/progress-circle/progress-circle.ts +++ b/src/components/progress-circle/progress-circle.ts @@ -3,6 +3,7 @@ import { HostBinding, ChangeDetectorRef, ChangeDetectionStrategy, + OnDestroy, Input } from '@angular/core'; @@ -41,13 +42,23 @@ type EasingFn = (currentTime: number, startValue: number, styleUrls: ['progress-circle.css'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MdProgressCircle { +export class MdProgressCircle implements OnDestroy { /** The id of the last requested animation. */ private _lastAnimationId: number = 0; /** The id of the indeterminate interval. */ private _interdeterminateInterval: number; + /** @internal */ + get interdeterminateInterval() { + return this._interdeterminateInterval; + } + /** @internal */ + set interdeterminateInterval(interval: number) { + clearInterval(this._interdeterminateInterval); + this._interdeterminateInterval = interval; + } + /** The current path value, representing the progres circle. */ private _currentPath: string; get currentPath() { @@ -60,6 +71,11 @@ export class MdProgressCircle { this._changeDetectorRef.markForCheck(); } + /** Clean up any animations that were running. */ + ngOnDestroy() { + this._cleanupIndeterminateAnimation(); + } + /** * Value of the progress circle. * @@ -162,8 +178,8 @@ export class MdProgressCircle { end = -temp; }; - if (!this._interdeterminateInterval) { - this._interdeterminateInterval = setInterval( + if (!this.interdeterminateInterval) { + this.interdeterminateInterval = setInterval( animate, duration + 50, 0, false); animate(); } @@ -174,10 +190,7 @@ export class MdProgressCircle { * Removes interval, ending the animation. */ private _cleanupIndeterminateAnimation() { - if (this._interdeterminateInterval) { - clearInterval(this._interdeterminateInterval); - this._interdeterminateInterval = null; - } + this.interdeterminateInterval = null; } } @@ -219,7 +232,7 @@ function clamp(v: number) { * Returns the current timestamp either based on the performance global or a date object. */ function now() { - if (typeof performance !== 'undefined') { + if (typeof performance !== 'undefined' && performance.now) { return performance.now(); } return Date.now();