mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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:
committed by
Andrew Seguin
parent
3b50d3d08f
commit
cf11ff2e3f
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user