mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
perf(progress-circle): clean up animation on destroy (#617)
The indeterminate animation is based on an interval that keeps running, even after the element has been destroyed. This change cleans up when the element is destroyed. Also adds an extra null check for `performance.now`.
This commit is contained in:
committed by
Jeremy Elbourn
parent
fda56173f8
commit
63f43bd1f0
@@ -74,6 +74,27 @@ describe('MdProgressCircular', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should clean up the indeterminate animation when the element is destroyed',
|
||||
(done: () => void) => {
|
||||
let template = `<md-progress-circle
|
||||
mode="indeterminate"
|
||||
*ngIf="!isHidden"></md-progress-circle>`;
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user