配置Angular Material Stepper:非线性模式下仅启用最后一步
Hey there! Let's fix your stepper so you can freely switch between the first two steps, but only access the third once both are fully completed. The main issue with your current code is that using registerForm && personalForm as the stepControl for the third step doesn't work—Angular Material expects a valid AbstractControl there, not a boolean condition. Here's how to implement the correct behavior:
Step 1: Update the Stepper HTML
First, we'll keep the non-linear behavior (allowing free switching between step 1 and 2) and add controls to block access to step 3 until both forms are valid:
<mat-horizontal-stepper #stepper [linear]="false" (selectionChange)="onStepSelectionChange($event)"> <ng-template matStepperIcon="edit"> <mat-icon>check</mat-icon> </ng-template> <!-- Step 1: Login Info --> <mat-step [stepControl]="registerForm" errorMessage="{{ 'REGISTRATION.STEPPER_ERROR_LOGIN' | translate }}"> <!-- Your login form content here --> </mat-step> <!-- Step 2: Personal Info --> <mat-step [stepControl]="personalForm" errorMessage="{{ 'REGISTRATION.STEPPER_ERROR_PERSONAL' | translate }}"> <!-- Your personal form content here --> </mat-step> <!-- Step 3: Review --> <mat-step [completed]="areFirstTwoFormsValid()" errorMessage="Überprüfung steht aus"> <!-- Your review content here --> </mat-step> </mat-horizontal-stepper>
Step 2: Update the Component TypeScript
Now, add the logic to prevent navigation to step 3 until both forms are valid, and handle the step selection change:
import { Component, OnInit, ViewChild } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { MatStepper, StepperSelectionEvent } from '@angular/material/stepper'; import { STEPPER_GLOBAL_OPTIONS } from '@angular/material/stepper'; @Component({ selector: 'app-registration', templateUrl: './registration.component.html', styleUrls: ['./registration.component.scss'], providers: [ { provide: STEPPER_GLOBAL_OPTIONS, useValue: { showError: true } } ] }) export class RegistrationComponent implements OnInit { @ViewChild('stepper') stepper: MatStepper; registerForm: FormGroup; personalForm: FormGroup; constructor(private fb: FormBuilder) {} ngOnInit(): void { // Initialize your forms with validators (example) this.registerForm = this.fb.group({ email: ['', [Validators.required, Validators.email]], password: ['', [Validators.required, Validators.minLength(6)]] }); this.personalForm = this.fb.group({ firstName: ['', Validators.required], lastName: ['', Validators.required], age: ['', Validators.required] }); } // Check if both first two forms are valid areFirstTwoFormsValid(): boolean { return this.registerForm.valid && this.personalForm.valid; } // Handle step selection to block access to step 3 if forms are invalid onStepSelectionChange(event: StepperSelectionEvent): void { // Step indexes are 0-based: 0 = Login, 1 = Personal, 2 = Review if (event.selectedIndex === 2 && !this.areFirstTwoFormsValid()) { // Prevent navigation to step 3, revert to previous step this.stepper.selectedIndex = event.previouslySelectedIndex; // Optional: Show user feedback (you can replace this with a Material snackbar) alert('Bitte geben Sie zuerst alle Anmelde- und persönlichen Daten ein!'); } } }
Key Changes Explained:
- Non-Linear Behavior: We explicitly set
[linear]="false"to keep free switching between step 1 and 2 (though this is the default, it's good to be explicit). - Step 3 Completion: The
[completed]property on step 3 uses our custom methodareFirstTwoFormsValid()to mark the step as completed only when both forms are valid. - Navigation Block: The
(selectionChange)event listener catches when the user tries to switch to step 3. If the forms are invalid, we revert them to their previous step and show feedback. - Removed Invalid Step Control: We replaced the incorrect
[stepControl]="registerForm && personalForm"with thecompletedcheck, since step 3 doesn't need its own form (it's just a review step).
This setup keeps the flexibility of switching between the first two steps while ensuring users can't jump to the review until all required info is filled out.
内容的提问来源于stack exchange,提问作者CptDayDreamer

