diff --git a/src/cdk/stepper/stepper.ts b/src/cdk/stepper/stepper.ts index 8d6db9dc481b..2846b882509d 100644 --- a/src/cdk/stepper/stepper.ts +++ b/src/cdk/stepper/stepper.ts @@ -28,12 +28,14 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, OnChanges, + OnDestroy } from '@angular/core'; import {LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE} from '@angular/cdk/keycodes'; import {CdkStepLabel} from './step-label'; import {coerceBooleanProperty} from '@angular/cdk/coercion'; import {AbstractControl} from '@angular/forms'; import {Direction, Directionality} from '@angular/cdk/bidi'; +import {Subject} from 'rxjs/Subject'; /** Used to generate unique ID for each stepper component. */ let nextId = 0; @@ -132,7 +134,10 @@ export class CdkStep implements OnChanges { selector: '[cdkStepper]', exportAs: 'cdkStepper', }) -export class CdkStepper { +export class CdkStepper implements OnDestroy { + /** Emits when the component is destroyed. */ + protected _destroyed = new Subject(); + /** The list of step components that the stepper is holding. */ @ContentChildren(CdkStep) _steps: QueryList; @@ -186,6 +191,11 @@ export class CdkStepper { this._groupId = nextId++; } + ngOnDestroy() { + this._destroyed.next(); + this._destroyed.complete(); + } + /** Selects and focuses the next step in list. */ next(): void { this.selectedIndex = Math.min(this._selectedIndex + 1, this._steps.length - 1); diff --git a/src/lib/stepper/stepper.ts b/src/lib/stepper/stepper.ts index 173d2d472604..fad6059712d6 100644 --- a/src/lib/stepper/stepper.ts +++ b/src/lib/stepper/stepper.ts @@ -9,6 +9,7 @@ import {animate, state, style, transition, trigger} from '@angular/animations'; import {CdkStep, CdkStepper} from '@angular/cdk/stepper'; import { + AfterContentInit, Component, ContentChild, ContentChildren, @@ -26,6 +27,7 @@ import {FormControl, FormGroupDirective, NgForm} from '@angular/forms'; import {ErrorStateMatcher} from '@angular/material/core'; import {MatStepHeader} from './step-header'; import {MatStepLabel} from './step-label'; +import {takeUntil} from 'rxjs/operators/takeUntil'; /** Workaround for https://github.com/angular/angular/issues/17849 */ export const _MatStep = CdkStep; @@ -66,12 +68,17 @@ export class MatStep extends _MatStep implements ErrorStateMatcher { @Directive({ selector: '[matStepper]' }) -export class MatStepper extends _MatStepper { +export class MatStepper extends _MatStepper implements AfterContentInit { /** The list of step headers of the steps in the stepper. */ @ViewChildren(MatStepHeader, {read: ElementRef}) _stepHeader: QueryList; /** Steps that the stepper holds. */ @ContentChildren(MatStep) _steps: QueryList; + + ngAfterContentInit() { + // Mark the component for change detection whenever the content children query changes + this._steps.changes.pipe(takeUntil(this._destroyed)).subscribe(() => this._stateChanged()); + } } @Component({