mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(stepper): emitting the animationDone event twice on some browsers (#13608)
Along the same lines as #13600 and #13587. The `animationDone` will be emitted twice in a row for some browsers due to a bug in `@angular/animations`.
This commit is contained in:
committed by
Joey Perrott
parent
16098a7802
commit
3ef933a6c8
@@ -28,7 +28,7 @@
|
||||
<div *ngFor="let step of _steps; let i = index"
|
||||
class="mat-horizontal-stepper-content" role="tabpanel"
|
||||
[@stepTransition]="_getAnimationDirection(i)"
|
||||
(@stepTransition.done)="_animationDone($event)"
|
||||
(@stepTransition.done)="_animationDone.next($event)"
|
||||
[id]="_getStepContentId(i)"
|
||||
[attr.aria-labelledby]="_getStepLabelId(i)"
|
||||
[attr.aria-expanded]="selectedIndex === i">
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="mat-vertical-content-container" [class.mat-stepper-vertical-line]="!isLast">
|
||||
<div class="mat-vertical-stepper-content" role="tabpanel"
|
||||
[@stepTransition]="_getAnimationDirection(i)"
|
||||
(@stepTransition.done)="_animationDone($event)"
|
||||
(@stepTransition.done)="_animationDone.next($event)"
|
||||
[id]="_getStepContentId(i)"
|
||||
[attr.aria-labelledby]="_getStepLabelId(i)"
|
||||
[attr.aria-expanded]="selectedIndex === i">
|
||||
|
||||
@@ -39,7 +39,8 @@ import {
|
||||
import {FormControl, FormGroupDirective, NgForm} from '@angular/forms';
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {ErrorStateMatcher} from '@angular/material/core';
|
||||
import {takeUntil} from 'rxjs/operators';
|
||||
import {Subject} from 'rxjs';
|
||||
import {takeUntil, distinctUntilChanged} from 'rxjs/operators';
|
||||
|
||||
import {MatStepHeader} from './step-header';
|
||||
import {MatStepLabel} from './step-label';
|
||||
@@ -102,18 +103,26 @@ export class MatStepper extends _CdkStepper implements AfterContentInit {
|
||||
/** Consumer-specified template-refs to be used to override the header icons. */
|
||||
_iconOverrides: {[key: string]: TemplateRef<MatStepperIconContext>} = {};
|
||||
|
||||
/** Stream of animation `done` events when the body expands/collapses. */
|
||||
_animationDone = new Subject<AnimationEvent>();
|
||||
|
||||
ngAfterContentInit() {
|
||||
const icons = this._icons.toArray();
|
||||
icons.forEach(({name, templateRef}) => this._iconOverrides[name] = templateRef);
|
||||
this._icons.forEach(({name, templateRef}) => this._iconOverrides[name] = templateRef);
|
||||
|
||||
// Mark the component for change detection whenever the content children query changes
|
||||
this._steps.changes.pipe(takeUntil(this._destroyed)).subscribe(() => this._stateChanged());
|
||||
}
|
||||
|
||||
_animationDone(event: AnimationEvent) {
|
||||
if ((event.toState as StepContentPositionState) === 'current') {
|
||||
this.animationDone.emit();
|
||||
}
|
||||
this._animationDone.pipe(
|
||||
// This needs a `distinctUntilChanged` in order to avoid emitting the same event twice due
|
||||
// to a bug in animations where the `.done` callback gets invoked twice on some browsers.
|
||||
// See https://github.com/angular/angular/issues/24084
|
||||
distinctUntilChanged((x, y) => x.fromState === y.fromState && x.toState === y.toState),
|
||||
takeUntil(this._destroyed)
|
||||
).subscribe(event => {
|
||||
if ((event.toState as StepContentPositionState) === 'current') {
|
||||
this.animationDone.emit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user