Kan ik de stappen van een mat-horizontale-stepper programmatisch verplaatsen in Angular / Angular Material

Ik heb een vraag over Angular Material (met Angular 4+). Stel dat ik in mijn componentsjabloon een <mat-horizontal-stepper>component toevoeg, en binnen elke stap <mat-step>heb ik stepper-knoppen om door de component te navigeren . Vind ik leuk zo…

<mat-horizontal-stepper>
  <mat-step>
    Step 1
    <button mat-button matStepperPrevious type="button">Back</button>
    <button mat-button matStepperNext type="button">Next</button>
  </mat-step>
  <mat-step>
    Step 2
    <button mat-button matStepperPrevious type="button">Back</button>
    <button mat-button matStepperNext type="button">Next</button>
  </mat-step>
  <mat-step>
    Step 3
    <button mat-button matStepperPrevious type="button">Back</button>
    <button mat-button matStepperNext type="button">Next</button>
  </mat-step>
</mat-horizontal-stepper>

Nu vraag ik me af of het mogelijk is om de knoppen uit elke stap te verwijderen en ze elders in de <mat-horizontal-stepper>op een statische positie of zelfs buiten de <mat-horizontal-stepper>en ik kan achteruit en vooruit navigeren met behulp van code in mijn component-typescript-bestand. Om een ​​idee te geven, ik zou graag willen dat mijn HTML er ongeveer zo uitziet

<mat-horizontal-stepper>
    <mat-step>
        Step 1
    </mat-step>
    <mat-step>
        Step 2
    </mat-step>
    <mat-step>
        Step 3
    </mat-step>
    <!-- one option -->
    <div>
       <button mat-button matStepperPrevious type="button">Back</button>
       <button mat-button matStepperNext type="button">Next</button>
    </div>
</mat-horizontal-stepper>
<!-- second option -->
<div>
   <button (click)="goBack()" type="button">Back</button>
   <button (click)="goForward()" type="button">Next</button>
</div>

Antwoord 1, autoriteit 100%

Ja. Het is mogelijk om naar een specifieke stepper te springen door de eigenschap selectedIndexvan de MatStepperte gebruiken. Ook onthult MatStepperopenbare methoden next()en previous(). Je kunt ze gebruiken om heen en weer te gaan.

In uw sjabloon:

Voeg een id toe aan je stepper, b.v. #stepper. Geef vervolgens in uw methoden goBack()en goForward()het stepper-ID door:

<mat-horizontal-stepper #stepper>
    <!-- Steps -->
</mat-horizontal-stepper>    
<!-- second option -->
<div>
   <button (click)="goBack(stepper)" type="button">Back</button>
   <button (click)="goForward(stepper)" type="button">Next</button>
</div>

.. en in je typoscript:

import { MatStepper } from '@angular/material/stepper';
goBack(stepper: MatStepper){
    stepper.previous();
}
goForward(stepper: MatStepper){
    stepper.next();
}

Link naar stackblitz-demo.


U kunt ook ViewChildgebruiken om een ​​verwijzing naar de stepper-component in uw TypeScript te krijgen, zoals hieronder weergegeven:

@ViewChild('stepper') private myStepper: MatStepper;
goBack(){
    this.myStepper.previous();
}
goForward(){
    this.myStepper.next();
}

In dit geval hoeft u de stepper-referentie niet door te geven in de methode in de html van uw component. Link naar Demo met ViewChild


U kunt de knoppen Backen Nextin-/uitschakelen door het volgende te gebruiken:

<button (click)="goBack(stepper)" type="button" 
        [disabled]="stepper.selectedIndex === 0">Back</button>
<button (click)="goForward(stepper)" type="button" 
        [disabled]="stepper.selectedIndex === stepper._steps.length-1">Next</button>

Antwoord 2, autoriteit 15%

Naast het antwoord van @Faisal, is dit mijn mening over het laten springen van de MatStepper zonder de stapper in de argumenten.

Dit is handig wanneer u meer flexibiliteit nodig heeft bij het manipuleren van de stepper, b.v. van een Serviceof iets anders.

HTML:

<div fxLayout="row" fxLayoutAlign="center center" fxLayoutGap="6px">
  <button (click)="move(0)">1st</button>
  <button (click)="move(1)">2nd</button>
  <button (click)="move(2)">3rd</button>
  <button (click)="move(3)">4th</button>
</div>

TS-bestand:

move(index: number) {
    this.stepper.selectedIndex = index;
}

Hier is de stackblitz-demo.


Antwoord 3, autoriteit 12%

Als je programmatisch wilt navigerennaar de volgende stap en als je een lineaire stepper gebruikt, volg dan de onderstaande stappen:

  • Maak een stepperals volgt: <mat-horizontal-stepper linear #matHorizontalStepper>

  • Definieer mat-stepals volgt: <mat-step [completed]="isThisStepDone">

  • Maak vanuit mat-stepeen knop om naar de volgende stap te gaan, zoals deze: <button (click)="next(matHorizontalStepper)">NEXT STEP</button>

  • In .tsbestand declareert u een MatStepperreferentie met de naam stepper:
    @ViewChild('matHorizontalStepper') stepper: MatStepper;

  • Ook binnen .ts-bestand initialiseert u isThisStepDoneals false: isThisStepDone: boolean = false;

  • Schrijf vervolgens de methode voor de VOLGENDE STAP-knop genaamd next():

    submit(stepper: MatStepper) {
      this.isThisStepDone = true;
      setTimeout(() => {           // or do some API calls/ Async events
       stepper.next();
      }, 1);
     }
    

OPMERKING: het async-gedeelte (setTimeout()) is vereistvanwege statuspropagatie via isThisStepDone.


Antwoord 4

Je zou het ook kunnen doen door de daadwerkelijke index van de stepper te specificeren met behulp van selectedIndex.

stackblitz:
https://stackblitz.com/edit/angular- 4rvy2s?file=app%2Fstepper-overzicht-voorbeeld.ts

HTML:

<div class="fab-nav-container">
   <mat-vertical-stepper linear="false" #stepper>
       <mat-step *ngFor="let step of stepNodes; let i = index">
           <ng-template matStepLabel>
               <p> {{step.title}} </p>
           </ng-template>
       </mat-step>
   </mat-vertical-stepper>
</div>
<div class="button-container">
   <div class="button-grp">
      <button mat-stroked-button (click)="clickButton(1, stepper)">1</button>
      <button mat-stroked-button (click)="clickButton(2, stepper)">2</button>
      <button mat-stroked-button (click)="clickButton(3, stepper)">3</button>
   </div>
</div>

TS:

import {Component, OnInit, ViewChild} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import { MatVerticalStepper } from '@angular/material';
import { MatStepper } from '@angular/material';
export interface INodes {
    title: string;
    seq: number;
    flowId: string;
}
/**
 * @title Stepper overview
 */
@Component({
  selector: 'stepper-overview-example',
  templateUrl: 'stepper-overview-example.html',
  styleUrls: ['stepper-overview-example.scss'],
})
export class StepperOverviewExample implements OnInit {
  @ViewChild(MatVerticalStepper) vert_stepper: MatVerticalStepper;
  @ViewChild('stepper') private myStepper: MatStepper;
  stepNodes: INodes[] = [
    { title: 'Request Submission', seq: 1, flowId: 'xasd12'}, 
    { title: 'Department Approval', seq: 2, flowId: 'erda23'}, 
    { title: 'Requestor Confirmation', seq: 3, flowId: 'fsyq51'}, 
  ];
  ngOnInit() {
  }
  ngAfterViewInit() {
    this.vert_stepper._getIndicatorType = () => 'number';
  }
  clickButton(index: number, stepper: MatStepper) {
      stepper.selectedIndex = index - 1;
  }
}

Other episodes