fix(stepper): error when selectedIndex is pre-set (#8035)

Fixes an error that is thrown if the `selectedIndex` is set before the steps are initialized.

Fixes #8031.
This commit is contained in:
Kristiyan Kostadinov
2017-11-02 05:06:26 +01:00
committed by Andrew Seguin
parent 3b50d3d08f
commit cf11ff2e3f
2 changed files with 42 additions and 9 deletions
+16 -9
View File
@@ -149,13 +149,17 @@ export class CdkStepper {
@Input()
get selectedIndex() { return this._selectedIndex; }
set selectedIndex(index: number) {
if (this._anyControlsInvalid(index)
|| index < this._selectedIndex && !this._steps.toArray()[index].editable) {
// remove focus from clicked step header if the step is not able to be selected
this._stepHeader.toArray()[index].nativeElement.blur();
} else if (this._selectedIndex != index) {
this._emitStepperSelectionEvent(index);
this._focusIndex = this._selectedIndex;
if (this._steps) {
if (this._anyControlsInvalid(index) || index < this._selectedIndex &&
!this._steps.toArray()[index].editable) {
// remove focus from clicked step header if the step is not able to be selected
this._stepHeader.toArray()[index].nativeElement.blur();
} else if (this._selectedIndex != index) {
this._emitStepperSelectionEvent(index);
this._focusIndex = this._selectedIndex;
}
} else {
this._selectedIndex = this._focusIndex = index;
}
}
private _selectedIndex: number = 0;
@@ -281,9 +285,12 @@ export class CdkStepper {
}
private _anyControlsInvalid(index: number): boolean {
this._steps.toArray()[this._selectedIndex].interacted = true;
const steps = this._steps.toArray();
steps[this._selectedIndex].interacted = true;
if (this._linear && index >= 0) {
return this._steps.toArray().slice(0, index).some(step => step.stepControl.invalid);
return steps.slice(0, index).some(step => step.stepControl && step.stepControl.invalid);
}
return false;
}
+26
View File
@@ -21,6 +21,7 @@ describe('MatHorizontalStepper', () => {
imports: [MatStepperModule, NoopAnimationsModule, ReactiveFormsModule],
declarations: [
SimpleMatHorizontalStepperApp,
SimplePreselectedMatHorizontalStepperApp,
LinearMatHorizontalStepperApp
],
providers: [
@@ -168,6 +169,18 @@ describe('MatHorizontalStepper', () => {
it('should be able to move to next step even when invalid if current step is optional', () => {
assertOptionalStepValidity(testComponent, fixture);
});
it('should not throw when there is a pre-defined selectedIndex', () => {
fixture.destroy();
let preselectedFixture = TestBed.createComponent(SimplePreselectedMatHorizontalStepperApp);
let debugElement = preselectedFixture.debugElement;
expect(() => preselectedFixture.detectChanges()).not.toThrow();
let stepHeaders = debugElement.queryAll(By.css('.mat-horizontal-stepper-header'));
assertSelectionChangeOnHeaderClick(preselectedFixture, stepHeaders);
});
});
});
@@ -862,3 +875,16 @@ class LinearMatVerticalStepperApp {
});
}
}
@Component({
template: `
<mat-horizontal-stepper [linear]="true" [selectedIndex]="index">
<mat-step label="One"></mat-step>
<mat-step label="Two"></mat-step>
<mat-step label="Three"></mat-step>
</mat-horizontal-stepper>
`
})
class SimplePreselectedMatHorizontalStepperApp {
index = 0;
}