Angular 7 - 使用路由的步进器组件

Angular 7 - Stepper component working with routing

我需要针对 Angular 7 的 Stepper 组件的检查解决方案,该解决方案可与 Angular 路由一起使用。

不是 Material Design Stepper - 它适用于简单的表单,但不适用于路由。

我尝试用 <mat-horizontal-stepper> 做的是这样的:

component.html:

<mat-horizontal-stepper (selectionChange)="selectionChanged($event)" [linear]="true">
    <mat-step *ngFor="let step of steps; let i = index" [label]="step.title">
        <router-outlet *ngIf="i === selectedStepIndex"></router-outlet>
    </mat-step>
</mat-horizontal-stepper>

component.ts:

public selectedStepIndex: number = 0;

selectionChanged(event: any) {
    this.selectedStepIndex= event.selectedIndex;
    const url = '/some-path/' + this.links[this.selectedStepIndex].path;
    this.router.navigate([url]);//using -> private router: Router
}

但是,由于某种原因,我无法返回。 Stepper 尝试向后导航,但它显示相同的页面,除非它是 stepper 的第一页 (i = 0)。

如果有任何建议(可能还有工作示例)或有关如何使用 <mat-horizontal-stepper> 实现此目的的详细信息,我将不胜感激。

你误解了<router-oulet>。它显示与您在路由模块中定义的路由匹配的组件。所以如果 <mat-step> 不触发 URL 变化或路线导航, <router-oulet> 显示相同组件:

您可以通过这样的逻辑实现您的意图:

[routerLink] 指令添加到 <mat-step>:

<mat-horizontal-stepper (selectionChange)="selectionChanged($event)" [linear]="true">
    <mat-step *ngFor="let step of steps; let i = index" [routerLink]="['/step' + i]" [label]="step.title">
        <router-outlet *ngIf="i === selectedStepIndex"></router-outlet>
    </mat-step>
</mat-horizontal-stepper>

在路由模块中定义组件的路由:

const routes: Routes = [
      //Just an example for the logic i used  
      { path: 'step0', component: StepOComponent },
      { path: 'step1', component: Step1Component },
      { path: 'step2', component: Step2Component },
    ]
 }
];

好的!我已经弄明白了:)

看起来 <mat-horizontal-stepper> 需要一些时间来重新加载显示的步骤,当涉及到 <router-outlet> - 所以我不得不手动强迫他等待。做这样的事情,它会工作得很好:

component.html:

<mat-horizontal-stepper (selectionChange)="selectionChanged($event)" [linear]="true">
    <mat-step *ngFor="let step of steps; let i = index" [label]="step.title">
        <div *ngIf="loadingStep">
            <mat-spinner></mat-spinner>
        </div>
        <div *ngIf="!loadingStep">
            <router-outlet *ngIf="i === selectedStepIndex"></router-outlet>
        </div>
    </mat-step>
</mat-horizontal-stepper>

component.ts:

public selectedStepIndex: number = 0;
public loadingStep: boolean = false;

selectionChanged(event: any) {
    this.selectedStepIndex = event.selectedIndex;
    if (event.previouslySelectedIndex > event.selectedIndex) {
        this.loadingStep = true;
        //Wait 1 sec. before showing the step
        setTimeout(() => {
            this.navigate();
            this.loadingStep = false;
        }, 1000);
    } else {
        this.navigate();
    }
}

private navigate(): void {
    const url = '/some-path/' + this.links[this.selectedStepIndex].path;
    this.router.navigate([url]);//using -> private router: Router
}

它并不完美,但对我来说已经足够好了:))

这对我有用

<mat-horizontal-stepper linear #stepper (selectionChange)="selectionChanged($event)">
    <mat-step [stepControl]="formFirst" [editable]="true">
        <ng-template matStepLabel>Product details</ng-template>
        <router-outlet *ngIf="0 === selectedStepIndex"></router-outlet>
    </mat-step>
    <mat-step>
        <ng-template matStepLabel>Key features</ng-template>
        <router-outlet *ngIf="1 === selectedStepIndex"></router-outlet>
    </mat-step>
</mat-horizontal-stepper>

函数

  selectionChanged($event): void {
    this.selectedStepIndex = $event.selectedIndex;
    switch ($event.selectedIndex) {
      case 0:
        this.router.navigate(['./'], { relativeTo: this.route });
        break;
      case 1:
        this.router.navigate(['./feature'], { relativeTo: this.route });
        break;
    }
  }