Angular / AngularMaterialでmat-h​​orizo​​ntal-stepperのステップをプログラムで移動できますか?


88

Angular Material(Angular 4+を使用)に関して質問があります。コンポーネントテンプレートでコンポーネントを追加する<mat-horizontal-stepper>と、各ステップ内<mat-step>にコンポーネントをナビゲートするためのステッパーボタンがあります。そのようです...

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

今、各ステップからボタンを削除<mat-horizontal-stepper>して、静的な位置またはの外側のどこかにボタンを配置することが可能かどうか疑問に思ってい<mat-horizontal-stepper>ます。コンポーネントのタイプスクリプトファイル内のコードを使用して前後に移動できます。アイデアを出すために、HTMLを次のようにしたいと思います

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

回答:


182

はい。のselectedIndexプロパティを使用して、特定のステッパーにジャンプすることができMatStepperます。また、 MatStepperパブリックメソッドnext()とを公​​開しますprevious()。それらを使用して前後に移動できます。

テンプレート内:

ステッパーにIDを追加します#stepper。次に、goBack()andgoForward()メソッドで、ステッパーIDを渡します。

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

..そしてあなたのタイプスクリプトで:

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

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

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

stackblitzデモへのリンク。


ViewChild以下に示すように、TypeScriptでステッパーコンポーネントへの参照を取得するために使用することもできます。

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

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

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

この場合、コンポーネントのhtmlのメソッドでステッパー参照を渡す必要はありません。ViewChildを使用したデモへのリンク


以下を使用して、BackおよびNextボタンを有効/無効にできます。

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

8
私はViewChildステッパーをどのように参照できるかを見ているだけでしたが、あなたは私をそれに打ち負かしました!無効化/有効化機能も追加したという事実が大好きです!いくつかのポイントがあります!
Mike Sav 2017

ViewChildステッパーを入手するのにも良いオプションです。しかし、私はIDを渡すことを好みます。ViewChildデモにもソリューションを追加しました\ o /
Faisal

こんにちはファイサルはそのような素晴らしい答えに感謝します、もう1つの助け、フォームをマットステップに渡す代わりに、角度のあるコンポーネントを渡すことができます、そしてそのコンポーネントが有効であることに応じて、次のマットステップにトラバースできます、それはどのように達成できますか、
ありがとう

素晴らしい解決策。しかし、実際のヘッダーではなく、ステッパーのコンテンツだけにスクロール領域を制限するにはどうすればよいでしょうか。コンテンツのヒープを追加すると、ヘッダーがスクロールして見えなくなります。ヘッダーは、ユーザーがプロセスのどこにいるかを示すため、各ステップのコンテンツの量に関係なく、ヘッダーが表示されることが重要です。
ウェインリーステラー2018

1
Angular 8を使用していて、@ ViewChildを使用している 場合は、staticを使用する必要があります:false@ViewChild('stepper', {static: false}) private myStepper: MatStepper; Per Angular、この値はAngular 9+リンクでデフォルトでfalseになります
rorvis

29

@ファイサルに加えての答えに、これは、引数でステッパーを渡す必要なしにMatStepperをジャンプさせることについての私の見解です。

これは、ステッパーをService他の何かから操作する際により柔軟性が必要な場合に役立ちます。

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ファイル:

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

これがstackblitzのデモです。


21

プログラムで次のステップに移動する場合、およびリニアステッパーを使用している場合は、以下の手順に従います。

  • 次のstepperように作成します。 <mat-horizontal-stepper linear #matHorizontalStepper>
  • 次のmat-stepように定義します。<mat-step [completed]="isThisStepDone">
  • 中から mat-step、次のような次のステップに進むためのボタンを作成します。 <button (click)="next(matHorizontalStepper)">NEXT STEP</button>
  • .tsファイルを宣言MatStepper参照という名前のステッパー
    @ViewChild('matHorizontalStepper') stepper: MatStepper;
  • また、.tsファイル内でfalseisThisStepDoneとして初期化しますisThisStepDone: boolean = false;
  • 次に、次の名前のNEXTSTEPボタンのメソッドを記述しますnext()

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

3
setTimeout()による状態伝播のため、非同期部分()が必要ですisThisStepDone
百合

2

selectedIndexを使用してステッパーの実際のインデックスを指定することによってもそれを行うことができます。

stackblitz: https

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

1
私は自分の関数@ViewChild('stepper') private myStepper: MatStepper;よりも使用this.matStepper.next();しているだけです。完全に機能
最大
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.