web-dev-qa-db-fra.com

Angular Composant pas à pas matériel pour chaque étape

J'ai un angular material linear stepper chaque étape est un angular component séparé contenant une form qui nécessite validation

La validation ne fonctionne tout simplement pas. Je peux passer à l'étape suivante sans remplir le formulaire. 

Pour illustrer ce que je veux dire, j’ai créé une version condensée sur stackblitz. 

La principale chose à regarder (je pense) est le create-profile.component.html

<mat-horizontal-stepper linear #stepper>
    <mat-step [stepControl]="frmStepOne">
        <ng-template matStepLabel>Step One Details</ng-template>
        <step-one-component></step-one-component>
    </mat-step>
    <mat-step [stepControl]="frmStepTwo">
        <ng-template matStepLabel>Step Two Details</ng-template>
        <step-two-component></step-two-component>
    </mat-step>
    <mat-step [stepControl]="frmStepThree">
        <ng-template matStepLabel>Step Three Details</ng-template>
        <step-three-component></step-three-component>
    </mat-step>
</mat-horizontal-stepper>

Et chaque step-X-component 

Voici le stackblitz. https://stackblitz.com/edit/angular-vpoj5j

5
Ben Donnelly

Le problème est dans votre CreateProfileComponent:

@Component({
    selector: 'create-profile-component',
    templateUrl: './create-profile.component.html'
})
export class CreateProfileComponent {

    frmStepOne: FormGroup;
    frmStepTwo: FormGroup;
    frmStepThree: FormGroup;

    constructor(private fb: FormBuilder) { }


}

Il n'y a pas de relation entre vos groupes de formulaires définis dans CreateProfileComponent et vos composants stepper. Vous avez essayé d'étendre chaque composant StepComponent avec CreateProfileComponent, mais avec cette approche, chaque composant StepComponent possède sa propre instance de CreateProfileComponent et, par conséquent, sa propre déclaration FormGroup.

Pour résoudre votre problème, vous pouvez déclarer des variables de modèle pour chaque composant StepComponent de votre code HTML (commençant par #) et transmettre le formulaireControl à [stepControl]:

<mat-horizontal-stepper linear #stepper>
    <mat-step [stepControl]="step1.frmStepOne">
        <ng-template matStepLabel>Step One Details</ng-template>
        <step-one-component #step1></step-one-component>
    </mat-step>
    <mat-step [stepControl]="step2.frmStepTwo">
        <ng-template matStepLabel>Step Two Details</ng-template>
        <step-two-component #step2></step-two-component>
    </mat-step>
    <mat-step [stepControl]="step3.frmStepThree">
        <ng-template matStepLabel>Step Three Details</ng-template>
        <step-three-component #step3></step-three-component>
    </mat-step>
</mat-horizontal-stepper>

Ou vous laissez votre code HTML tel quel et travaillez avec ViewChild () (Mon approche préférée).

@Component({
    selector: 'create-profile-component',
    templateUrl: './create-profile.component.html'
})

export class CreateProfileComponent {

    @ViewChild(StepOneComponent) stepOneComponent: StepOneComponent;
    @ViewChild(StepTwoComponent) stepTwoComponent: StepTwoComponent;
    @ViewChild(StepTwoComponent) stepThreeComponent: StepThreeComponent;

    get frmStepOne() {
       return this.stepOneComponent ? this.stepOneComponent.frmStepOn : null;
    }

    get frmStepTwo() {
       return this.stepTwoComponent ? this.stepTwoComponent.frmStepTwo : null;
    }

    get frmStepThree() {
       return this.stepThreeComponent ? this.stepThreeComponent.frmStepThree : null;
    }

}

Quoi qu'il en soit, il n'est pas nécessaire d'étendre vos composants StepComponents avec CreateProfileComponent et cela n'a aucun sens.

@Component({
    selector: 'step-x-component',
    templateUrl: './step-x.component.html',
})
export class StepXComponent {

    public formStepX: FormGroup;

    constructor(private formBuilder: FormBuilder) {
    }

    ngOnInit() {
        this.frmStepX = this.formBuilder.group({
            name: ['', Validators.required]
        });

    }

}
13
SplitterAlex

Votre stepper et vos composants fonctionnent avec différents objets de formulaire. Vous devez définir les objets de formulaire de super dans la fonction ngONInit() du composant step

ngOnInit() {
    super.frmStepTwo = this.formBuilder.group({
        address: ['', Validators.required]
    });

au lieu 

ngOnInit() {
    this.frmStepTwo = this.formBuilder.group({
        address: ['', Validators.required]
    });
0
Mehmet Sunkur