Czy mogę programowo przesuwać kroki krokowego poziomego maty w materiale kątowym / kątowym

85

Mam pytanie dotyczące Angular Material (z Angular 4+). Powiedz w moim szablonie komponentów, że dodaję <mat-horizontal-stepper>komponent, a na każdym kroku <mat-step>mam przyciski krokowe do nawigacji po komponencie. Tak jak tak ...

<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>

Teraz zastanawiam się, czy możliwe jest usunięcie przycisków z każdego kroku i umieszczenie ich w innym miejscu <mat-horizontal-stepper>w pozycji statycznej lub nawet poza <mat-horizontal-stepper>i mogę nawigować wstecz i do przodu za pomocą kodu w moim pliku maszynopisu komponentu. Aby dać pomysł, chciałbym, aby mój HTML wyglądał mniej więcej tak

<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>
Mike Sav
źródło

Odpowiedzi:

173

Tak. Do konkretnego steppera można przejść za pomocą selectedIndexwłaściwości MatStepper. Ponadto MatStepperujawnia metody publiczne next()i previous(). Możesz ich używać do poruszania się w tę iz powrotem.

W Twoim szablonie:

Dodaj identyfikator do swojego steppera np #stepper. Następnie w swoich goBack()i goForward()metodach podaj identyfikator steppera:

<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>

.. iw maszynopisie:

import { MatStepper } from '@angular/material/stepper';

goBack(stepper: MatStepper){
    stepper.previous();
}

goForward(stepper: MatStepper){
    stepper.next();
}

Link do dema stackblitz .


Możesz również użyć, ViewChildaby uzyskać odwołanie do składnika krokowego w swoim TypeScript, jak pokazano poniżej:

@ViewChild('stepper') private myStepper: MatStepper;

goBack(){
    this.myStepper.previous();
}

goForward(){
    this.myStepper.next();
}

W takim przypadku nie musisz przekazywać odwołania do steppera w metodzie w html twojego komponentu. Link do wersji demonstracyjnej za pomocą ViewChild


Możesz włączyć / wyłączyć przyciski Backi Next, korzystając z:

<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>
Faisal
źródło
8
Właśnie patrzyłem ViewChildi widziałem, jak mogę się odnieść do Steppera - ale pokonałeś mnie w tym! Podoba mi się fakt, że dodałeś również funkcję wyłączania / włączania! Miej kilka punktów!
Mike Sav
ViewChildjest również dobrą opcją na zakup stepera. Ale wolałbym przekazać legitymację. Dodałem też ViewChildrozwiązanie w wersji demo \ o /
Faisal
Cześć Faisal, dziękuję za tak świetną odpowiedź, jeszcze jedna pomoc, zamiast przekazywać formularz do kroku, czy możemy przekazać komponenty kątowe, a następnie, w zależności od tego, czy składnik jest ważny, czy mogę przejść do następnego kroku mat, jak to osiągnąć , dziękuję
Enthu
Niezłe rozwiązanie. Ale jak możemy ograniczyć obszar przewijania tylko do zawartości steppera, a nie do faktycznego nagłówka. Jeśli dodasz stosy treści, nagłówek przewinie się poza zasięgiem wzroku. Ponieważ nagłówek wskazuje, gdzie użytkownik jest w jakimś procesie, ważne jest, aby nagłówek był widoczny niezależnie od ilości treści w każdym kroku.
Wayne Riesterer
Tutaj ikony ukończonych kroków są ustawione na „EDYTUJ”, a ikona bieżących kroków jest ustawiona na „NUMER” Czy mogę mieć ikonę ukończonych kroków jako „ZAKOŃCZONE (zaznacz)”, a po naciśnięciu przycisku Wstecz ikona ukończonego kroku zmieni się na „Edytuj” .... EX: załóżmy, że wykonałem krok 2 i kliknąłem następny przycisk, teraz ikona kroku 2 jest wyświetlana jako „Ikona EDYTUJ (symbol pióra)”, a teraz jestem w kroku 3, który pokazuje „Numer” jako ikonę .... Co Chcę zrobić to Kiedy następny btn kliknięto z kroku 2, ikona powinna być "DONE", a ikona trzeciego kroku powinna być "Number", jeśli kliknąłem wstecz btn 3 kroku, ikona 3 kroku powinna być "DONE". "EDYTOWAĆ".
Zhu
29

Oprócz odpowiedzi @ Faisal , to jest moje podejście do wykonywania skoku MatSteppera bez konieczności przekazywania steppera w argumentach.

Jest to pomocne, gdy potrzebujesz większej elastyczności w manipulowaniu stepperem np. Z Serviceczegoś innego.

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>

Plik TS:

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

Oto demo stackblitz .

Altus
źródło
21

Jeśli chcesz programowo przejść do następnego kroku i używasz liniowego steppera , wykonaj poniższe czynności:

  • Utwórz steppertaki: <mat-horizontal-stepper linear #matHorizontalStepper>
  • Zdefiniuj w mat-stepten sposób:<mat-step [completed]="isThisStepDone">
  • Od wewnątrz mat-steputwórz przycisk, aby przejść do następnego kroku, takiego jak ten: <button (click)="next(matHorizontalStepper)">NEXT STEP</button>
  • W .tspliku zadeklaruj MatStepperodwołanie o nazwie stepper :
    @ViewChild('matHorizontalStepper') stepper: MatStepper;
  • Również wewnątrz .tspliku inicjalizuj isThisStepDonejako fałsz :isThisStepDone: boolean = false;
  • Następnie napisz metodę dla przycisku NEXT STEP o nazwie next():

    submit(stepper: MatStepper) {
     this.isThisStepDone = true;
     setTimeout(() => {           // or do some API calls/ Async events
      stepper.next();
     }, 1);
    }
    
Czarnobrody
źródło
3
Async part ( setTimeout()) jest wymagana ze względu na propagację stanu za pośrednictwem isThisStepDone.
Yuri
2

Możesz to również zrobić, podając rzeczywisty indeks steppera za pomocą selectedIndex.

stackblitz: https://stackblitz.com/edit/angular-4rvy2s?file=app%2Fstepper-overview-example.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;
  }
}
M.Laida
źródło
1
Po prostu używam @ViewChild('stepper') private myStepper: MatStepper;i niż this.matStepper.next();w mojej funkcji. Działa idealnie
maks.