Angular Material Stepper:禁用标题导航

61

我希望只能通过“下一步”和“上一步”按钮来导航步进器。

由于用户还可以单击每个步骤标签以导航到任何步骤,因此我无法做到这一点。我不能使用线性布局,因为它需要每个步骤都有一个formArrayFormGroup

我尝试过使用<mat-step (click)="$event.stopPropagation()">


你在寻找解决方案方面有什么进展吗? - Deniss M.
15个回答

126

将以下内容添加到您的样式表中。我试图禁用页眉导航栏。尝试了许多方法,但这个hack起作用了。在Angular Material团队支持此功能之前,您可以尝试使用它。

::ng-deep .mat-horizontal-stepper-header{
    pointer-events: none !important;
}

2
这个不起作用,我仍然可以通过标题导航到上一步。 - Mel
8
请在您的主要style.css或style.scss文件末尾添加以下代码块。它将生效。 - Shahzaib Shahid
1
@ShahzaibShahid 为什么将它添加到组件的 scss 文件中不起作用?为什么必须是共享的 style.scss 文件? - Ka Mok
3
如果您使用ng-deep,它就有效: ::ng-deep .mat-horizontal-stepper-header {...} - Engam
是的,它有效,除非您正在使用垂直步进器,在这种情况下,它是 ::ng-deep .mat-vertical-stepper-header{ pointer-events: none !important; } - Darren Street
显示剩余3条评论

74

使用带有completed=falselinear步进器。当用户按下按钮时,通过编程方式完成该步骤并移至下一个步骤。

这样您就不需要操作CSS指针事件。在我们的应用中,这导致了与NVDA的可访问性问题。

    <mat-horizontal-stepper linear #stepper>
      <mat-step completed="false">
        <ng-template matStepLabel>Step 1</ng-template>
        <app-some-child (nextClicked)="nextClicked($event)" ></app-some-child>
      </mat-step>
      <mat-step>
        <ng-template matStepLabel>Step 2</ng-template>
        <app-some-other-child></app-some-other-child>
      </mat-step>
    </mat-horizontal-stepper>
    
    export class AppComponent implements OnInit {

      @ViewChild('stepper') stepper: MatStepper;

      nextClicked(event) {
        // complete the current step
        this.stepper.selected.completed = true;
        // move to next step
        this.stepper.next();
      }
    }


11
这是正确的做法。 - Mickers
8
很棒的解决方案!请注意,它不会阻止用户在第二步时返回第一步(这可能是您需要的)。 为此,您可以将 editable="false" 添加到您的 mat-step 中。 - dekajoo
很好的解决方案!谢谢。 - AGrammerPro
1
不好的解决方案,它不能禁用“下一步”步骤,以前的步骤也不会变灰。CSS是更正确的解决方案。 - roma2341
好的回答和正确的实现方式 - Kumaresan Sd
似乎很明显,但如果您不将所选步骤设置为已完成,则步进器不会移动。如果您想禁用上一步骤,也可以设置 this.stepper.selected.editable = false - Low

8

没有::ng-deep就不起作用。

    ::ng-deep .mat-horizontal-stepper-header{
      pointer-events: none !important;
    }

8

如果::ng-deep不起作用,仍在寻找替代方案的人可以尝试其他解决方法。

此外,::ng-deep已被弃用,如果您想使用CSS进行操作,则将ViewEncapsulation设置为none是首选方式。

在您的component.ts中导入ViewEncapsulation并将其设置为None:

import { Component, OnInit, ViewEncapsulation } from "@angular/core";

@Component({
  selector: "stepper-overview-example",
  templateUrl: "stepper-overview-example.html",
  styleUrls: ["stepper-overview-example.css"],
  encapsulation: ViewEncapsulation.None
})
export class StepperOverviewExample implements OnInit {
  isLinear = false;

  constructor() {}

  ngOnInit() {}
}

在你的组件样式表 component.css 中,将 pointer-events 设置为 none
.mat-horizontal-stepper-header { 
  pointer-events: none !important; 
}

Here's a DEMO.


谢谢!我有一个嵌套的步进器,你在这里提到的封装属性起了很大的作用 (y) - lucniner
ViewEncapsulation None 不是一个好主意。这应该保留给最终的“没有其他可能的选择”的情况。副作用不会很明显,你会在长时间内以错误的方式发现它们的形式。有很多奇怪的问题,例如样式被选中和/或应用到所有错误的位置。如果您选择了这条路,请在发布应用程序之前对整个应用程序进行一些严格的点检。 - mwilson

8

不要使用 ::ng-deep,因为它已经被弃用。

https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep

如果你正在使用Angular Material,请使用文档中的主题指南。

https://material.angular.io/guide/theming

以下是样式实现的示例:

my-custom-elements.scss

@import '~@angular/material/theming';

@mixin custom-stepper-theme() {
  .mat-horizontal-stepper-header {
    pointer-events: none;
  }
}

global-material-theme.scss

@import '~@angular/material/theming';
// Plus imports for other components in your app.

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();

@import './material/my-custom-elements.scss';

@include custom-stepper-theme();

angular.json

...
"styles": ["src/styles.scss", "src/app/global-material-theme.scss"]
...

我该如何为我的Angular应用程序中的一个组件进行定制? - Duc Nguyen
将其放在不同的类上。并使用类规范(然后您可以在该组件的scss中定义mixin,这是更好的代码实践,以说明它是一种特定的样式)。 - Jorge Mussato

5

为了改进接受的答案,如果您有垂直步进器,则该答案将无效。

为了防止用户能够单击标题并导航,请在根目录的style.css文件中添加以下代码:

.mat-step-header {
  pointer-events: none !important;
}

这将确保它适用于mat-horizontal-stepper-headermat-vertical-stepper-header


3
我为此找到了一个有点取巧的解决方案。问题在于您无法完全禁用标题导航,但可以防止其在特定时刻之前被启用。
这个时刻是“form.invalid”。
我的情况是:用户需要填写步骤内的表格,点击“保存”按钮,然后才能使用“NEXT”按钮并继续导航(也可以返回)。
我所做的是引入另一个“隐藏”的“input”,它将使用angular的“[required]”动态属性。如果上一个“save”条件不成功,则只有该字段才是“必填”的。一旦它成功,这个字段就不再是“必填”的了,用户就可以进一步导航。
与mat-stepper(或md-stepper)属性“editable”一起,您应该能够实现您想要的效果。
如果你完全理解这个想法,请告诉我。

2

这对我也起了作用。

要求:

  • 仅当
    有效时,允许从导航或下一步按钮导航
  • 禁用标题导航并保持按钮禁用状态,直到表单无效为止。

 <mat-horizontal-stepper #stepper [linear]="true">

    <!----------------------------->
    <!---- STEP: 1:---->
    <!----------------------------->

    <mat-step #generalStep [completed]="formGroup1.valid">
      <ng-template matStepLabel>Step-1</ng-template>
      
      <form [formGroup]="formGroup1">

      // STEP-1 Content
      // matInput - with form control bindings

       <div class="container">
          <button mat-raised-button matStepperNext color="primary"[disabled]="!formGroup1.valid">Next Step</button>
        </div>

      </form>

    </mat-step>

    <!------------------------------->
    <!-- STEP: 2:-->
    <!------------------------------->


    <mat-step #generalStep [completed]="formGroup2.valid">
      <ng-template matStepLabel>Step-2</ng-template>

      <form [formGroup]="formGroup2">

      // STEP-2 Content
      // matInput - with form control bindings

      <button mat-raised-button matStepperNext color="primary"[disabled]="!formGroup.valid">Next Step</button>

      </form>
    </mat-step>

  
  </mat-horizontal-stepper>

  • FormGroup/FormControl初始化
  • 添加验证器
  formGroup1: FormGroup;
  formGroup2: FormGroup;

   this.formGroup1 = this.formBuilder.group({
      control1: new FormControl('', [Validators.required]),
      control2: new FormControl('', [Validators.required]),
    });

  this.formGroup2 = this.formBuilder.group({
    control3: new FormControl('', [Validators.required]),
    control4: new FormControl('', [Validators.required]),
  });


2

以下内容对我有效,启用“上一步”后单击即可:

::ng-deep .mat-vertical-stepper-header:not([ng-reflect-active="true"]){
    pointer-events: none !important;
}

要创建水平步进条,请按照以下步骤进行:

::ng-deep .mat-horizontal-stepper-header:not([ng-reflect-active="true"]){
        pointer-events: none !important;
}

1

首先,您需要在组件配置中添加ViewEncapsulation.None

@Component({
 selector: 'app-example',
 encapsulation: `ViewEncapsulation.None`
 })

然后在您的组件CSS中添加此内容。

.mat-horizontal-stepper-header-container  {
  display: none !important;
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接